FFmpeg
Loading...
Searching...
No Matches
rasm.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Ramiro Polla
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#ifndef SWSCALE_AARCH64_RASM_H
22#define SWSCALE_AARCH64_RASM_H
23
24#include <stdbool.h>
25#include <stddef.h>
26#include <stdint.h>
27#include <stdio.h>
28
30#include "libavutil/bprint.h"
31#include "libavutil/avassert.h"
32
33/**
34 * Runtime assembler for AArch64. Provides an instruction-level IR and
35 * builder API tailored to the needs of the swscale dynamic pipeline.
36 * NOTE: Currently only a static file backend, which emits GNU assembler
37 * text, has been implemented.
38 */
39
40/*********************************************************************/
41/* Instruction operands */
42
43/* A packed 64-bit value representing a single instruction operand. */
44typedef union RasmOp {
45 uint8_t u8 [8];
46 uint16_t u16[4];
47 uint32_t u32[2];
48 uint64_t u64;
49} RasmOp;
50
51static inline RasmOp rasm_op_new(int type)
52{
53 RasmOp op = { 0 };
54 op.u8[7] = type;
55 return op;
56}
57
58static inline uint8_t rasm_op_type(RasmOp op) { return op.u8[7]; }
59
60/* Generic operand types */
61
68
69/* RASM_OP_NONE */
70
71static inline RasmOp rasm_op_none(void)
72{
74}
75
76#define OPN rasm_op_none()
77
78/* RASM_OP_IMM */
79
81{
83 op.u32[0] = (uint32_t) val;
84 return op;
85}
86
88{
89 return (int32_t) op.u32[0];
90}
91
92#define IMM(val) rasm_op_imm(val)
93
94/* RASM_OP_LABEL */
95
96static inline RasmOp rasm_op_label(int id)
97{
99 op.u16[0] = (uint16_t) id;
100 return op;
101}
102
103static inline int rasm_op_label_id(RasmOp op)
104{
105 return (int) op.u16[0];
106}
107
108/*********************************************************************/
109/* IR Nodes */
110
120
121typedef struct RasmNodeInsn {
122 int id;
125
126typedef struct RasmNodeComment {
127 char *text;
129
130typedef struct RasmNodeLabel {
131 int id;
133
134typedef struct RasmNodeFunc {
135 char *name;
136 bool export;
139
140typedef struct RasmNodeDirective {
141 char *text;
143
144/* A single node in the IR. */
158
159/*********************************************************************/
160/* Top-level IR entries */
161
162typedef enum RasmEntryType {
164 RASM_ENTRY_DATA, /* NOTE not yet implemented */
166
167typedef struct RasmFunction {
168 bool export;
171
172/* A contiguous range of nodes. */
181
182/*********************************************************************/
183/* Main runtime assembler context */
184
194
196void rasm_free(RasmContext **prctx);
197
198/* IR Nodes */
199RasmNode *rasm_add_insn(RasmContext *rctx, int id,
200 RasmOp op0, RasmOp op1, RasmOp op2, RasmOp op3);
201RasmNode *rasm_add_comment(RasmContext *rctx, const char *comment);
202RasmNode *rasm_add_commentf(RasmContext *rctx, char *s, size_t n,
203 const char *fmt, ...) av_printf_format(4, 5);
204RasmNode *rasm_add_label(RasmContext *rctx, int id);
205RasmNode *rasm_add_func(RasmContext *rctx, int id, bool export,
206 bool jumpable);
208RasmNode *rasm_add_directive(RasmContext *rctx, const char *text);
209
212
213/* Top-level IR entries */
214int rasm_func_begin(RasmContext *rctx, const char *name, bool export,
215 bool jumpable);
216
217/**
218 * Allocate a new label ID with the given name.
219 *
220 * @param name label name or NULL for local label
221 * @return new label ID, negative error code on failure
222 */
223int rasm_new_label(RasmContext *rctx, const char *name);
224int rasm_new_labelf(RasmContext *rctx, char *s, size_t n,
225 const char *fmt, ...) av_printf_format(4, 5);
226
227/* Annotate current instruction node in the IR. */
228void rasm_annotate(RasmContext *rctx, const char *comment);
229void rasm_annotatef(RasmContext *rctx, char *s, size_t n,
230 const char *fmt, ...) av_printf_format(4, 5);
231
232/* Annotate next instruction node added to the IR. */
233void rasm_annotate_next(RasmContext *rctx, const char *comment);
234void rasm_annotate_nextf(RasmContext *rctx, char *s, size_t n,
235 const char *fmt, ...) av_printf_format(4, 5);
236
237/* Emit the assembled IR as GNU assembler text to bp. */
238int rasm_print(RasmContext *rctx, AVBPrint *bp);
239
240/*********************************************************************/
241/* AArch64-specific */
242
243/* Supported AArch64 instructions */
309
310/* Supported AArch64 operand types */
319
320/* AArch64 condition codes */
321#define AARCH64_COND_EQ 0x0
322#define AARCH64_COND_NE 0x1
323#define AARCH64_COND_HS 0x2
324#define AARCH64_COND_CS AARCH64_COND_HS
325#define AARCH64_COND_LO 0x3
326#define AARCH64_COND_CC AARCH64_COND_LO
327#define AARCH64_COND_MI 0x4
328#define AARCH64_COND_PL 0x5
329#define AARCH64_COND_VS 0x6
330#define AARCH64_COND_VC 0x7
331#define AARCH64_COND_HI 0x8
332#define AARCH64_COND_LS 0x9
333#define AARCH64_COND_GE 0xa
334#define AARCH64_COND_LT 0xb
335#define AARCH64_COND_GT 0xc
336#define AARCH64_COND_LE 0xd
337#define AARCH64_COND_AL 0xe
338#define AARCH64_COND_NV 0xf
339
340/*********************************************************************/
341/* AARCH64_OP_GPR */
342
343static inline RasmOp a64op_make_gpr(uint8_t n, uint8_t size)
344{
346 op.u8[0] = n;
347 op.u8[1] = size;
348 return op;
349}
350
351static inline uint8_t a64op_gpr_n (RasmOp op) { return op.u8[0]; }
352static inline uint8_t a64op_gpr_size(RasmOp op) { return op.u8[1]; }
353
354static inline RasmOp a64op_gpw(uint8_t n) { return a64op_make_gpr(n, sizeof(uint32_t)); }
355static inline RasmOp a64op_gpx(uint8_t n) { return a64op_make_gpr(n, sizeof(uint64_t)); }
356static inline RasmOp a64op_lr (void) { return a64op_make_gpr(30, sizeof(uint64_t)); }
357static inline RasmOp a64op_sp (void) { return a64op_make_gpr(31, sizeof(uint64_t)); }
358
359/* modifiers */
360static inline RasmOp a64op_w(RasmOp op) { return a64op_gpw(a64op_gpr_n(op)); }
361static inline RasmOp a64op_x(RasmOp op) { return a64op_gpx(a64op_gpr_n(op)); }
362
363/*********************************************************************/
364/* AARCH64_OP_VEC */
365
366static inline RasmOp a64op_make_vec(uint8_t n, uint8_t el_count, uint8_t el_size)
367{
369 op.u8[0] = n;
370 op.u8[1] = el_count;
371 op.u8[2] = el_size;
372 op.u8[3] = 0; /* num_regs */
373 op.u8[4] = 0; /* idx_p1 */
374 return op;
375}
376
377static inline uint8_t a64op_vec_n (RasmOp op) { return op.u8[0]; }
378static inline uint8_t a64op_vec_el_count(RasmOp op) { return op.u8[1]; }
379static inline uint8_t a64op_vec_el_size (RasmOp op) { return op.u8[2]; }
380static inline uint8_t a64op_vec_num_regs(RasmOp op) { return op.u8[3]; }
381static inline uint8_t a64op_vec_idx_p1 (RasmOp op) { return op.u8[4]; }
382
383static inline RasmOp a64op_vec (uint8_t n) { return a64op_make_vec(n, 0, 0); }
384static inline RasmOp a64op_vecb (uint8_t n) { return a64op_make_vec(n, 0, 1); }
385static inline RasmOp a64op_vech (uint8_t n) { return a64op_make_vec(n, 0, 2); }
386static inline RasmOp a64op_vecs (uint8_t n) { return a64op_make_vec(n, 0, 4); }
387static inline RasmOp a64op_vecd (uint8_t n) { return a64op_make_vec(n, 0, 8); }
388static inline RasmOp a64op_vecq (uint8_t n) { return a64op_make_vec(n, 0, 16); }
389static inline RasmOp a64op_vec8b (uint8_t n) { return a64op_make_vec(n, 8, 1); }
390static inline RasmOp a64op_vec16b(uint8_t n) { return a64op_make_vec(n, 16, 1); }
391static inline RasmOp a64op_vec4h (uint8_t n) { return a64op_make_vec(n, 4, 2); }
392static inline RasmOp a64op_vec8h (uint8_t n) { return a64op_make_vec(n, 8, 2); }
393static inline RasmOp a64op_vec2s (uint8_t n) { return a64op_make_vec(n, 2, 4); }
394static inline RasmOp a64op_vec4s (uint8_t n) { return a64op_make_vec(n, 4, 4); }
395static inline RasmOp a64op_vec2d (uint8_t n) { return a64op_make_vec(n, 2, 8); }
396
397/**
398 * Create register-list operand for structured load/store instructions.
399 * Registers must be consecutive.
400 */
401static inline RasmOp a64op_veclist(RasmOp op0, RasmOp op1, RasmOp op2, RasmOp op3)
402{
404 uint8_t num_regs = 1;
405 if (rasm_op_type(op1) != RASM_OP_NONE) {
406 av_assert0(((a64op_vec_n(op0) + 1) & 0x1f) == a64op_vec_n(op1));
407 num_regs++;
408 if (rasm_op_type(op2) != RASM_OP_NONE) {
409 av_assert0(((a64op_vec_n(op1) + 1) & 0x1f) == a64op_vec_n(op2));
410 num_regs++;
411 if (rasm_op_type(op3) != RASM_OP_NONE) {
412 av_assert0(((a64op_vec_n(op2) + 1) & 0x1f) == a64op_vec_n(op3));
413 num_regs++;
414 }
415 }
416 }
417 op0.u8[3] = num_regs;
418 return op0;
419}
420
421/* by-element modifier */
422static inline RasmOp a64op_elem(RasmOp op, uint8_t idx)
423{
424 op.u8[1] = 0; /* el_count */
425 op.u8[4] = idx + 1;
426 return op;
427}
428
429/* scalar modifiers */
430static inline RasmOp v_b(RasmOp op) { return a64op_vecb(a64op_vec_n(op)); }
431static inline RasmOp v_h(RasmOp op) { return a64op_vech(a64op_vec_n(op)); }
432static inline RasmOp v_s(RasmOp op) { return a64op_vecs(a64op_vec_n(op)); }
433static inline RasmOp v_d(RasmOp op) { return a64op_vecd(a64op_vec_n(op)); }
434static inline RasmOp v_q(RasmOp op) { return a64op_vecq(a64op_vec_n(op)); }
435
436/* arrangement specifier modifiers */
437static inline RasmOp v_8b (RasmOp op) { return a64op_vec8b (a64op_vec_n(op)); }
438static inline RasmOp v_16b(RasmOp op) { return a64op_vec16b(a64op_vec_n(op)); }
439static inline RasmOp v_4h (RasmOp op) { return a64op_vec4h (a64op_vec_n(op)); }
440static inline RasmOp v_8h (RasmOp op) { return a64op_vec8h (a64op_vec_n(op)); }
441static inline RasmOp v_2s (RasmOp op) { return a64op_vec2s (a64op_vec_n(op)); }
442static inline RasmOp v_4s (RasmOp op) { return a64op_vec4s (a64op_vec_n(op)); }
443static inline RasmOp v_2d (RasmOp op) { return a64op_vec2d (a64op_vec_n(op)); }
444
445/* register-list modifiers */
446static inline RasmOp vv_1(RasmOp op0) { return a64op_veclist(op0, OPN, OPN, OPN); }
447static inline RasmOp vv_2(RasmOp op0, RasmOp op1) { return a64op_veclist(op0, op1, OPN, OPN); }
448static inline RasmOp vv_3(RasmOp op0, RasmOp op1, RasmOp op2) { return a64op_veclist(op0, op1, op2, OPN); }
449static inline RasmOp vv_4(RasmOp op0, RasmOp op1, RasmOp op2, RasmOp op3) { return a64op_veclist(op0, op1, op2, op3); }
450
451/**
452 * This helper structure is used to mimic the assembler syntax for vector
453 * register modifiers. This simplifies writing code with expressions such
454 * as vtmp.s and vtmp.b16 instead of v_s(vtmp) and v_16b(vtmp).
455 */
456typedef struct AArch64VecViews {
457 /* scalar */
463 /* arrangement specifier */
471 /* by element */
472 RasmOp be[2]; /* NOTE it should be 16 but we only use 2 so far. */
475
476/* Fill vector view struct for given op. */
478
479#define A64OP_VEC_VIEWS4(op) { \
480 a64op_vec_views((op)[0]), \
481 a64op_vec_views((op)[1]), \
482 a64op_vec_views((op)[2]), \
483 a64op_vec_views((op)[3]), \
484}
485
486/*********************************************************************/
487/* AARCH64_OP_BASE */
488
489#define AARCH64_BASE_OFFSET 0
490#define AARCH64_BASE_PRE 1
491#define AARCH64_BASE_POST 2
492
493static inline RasmOp a64op_make_base(uint8_t n, uint8_t mode, int16_t imm)
494{
496 op.u16[0] = (uint16_t) imm;
497 op.u8[2] = n;
498 op.u8[3] = mode;
499 return op;
500}
501
502static inline int16_t a64op_base_imm (RasmOp op) { return (int16_t) op.u16[0]; }
503static inline uint8_t a64op_base_n (RasmOp op) { return op.u8[2]; }
504static inline uint8_t a64op_base_mode(RasmOp op) { return op.u8[3]; }
505
507static inline RasmOp a64op_off (RasmOp op, int16_t imm) { return a64op_make_base(a64op_gpr_n(op), AARCH64_BASE_OFFSET, imm); }
508static inline RasmOp a64op_pre (RasmOp op, int16_t imm) { return a64op_make_base(a64op_gpr_n(op), AARCH64_BASE_PRE, imm); }
509static inline RasmOp a64op_post(RasmOp op, int16_t imm) { return a64op_make_base(a64op_gpr_n(op), AARCH64_BASE_POST, imm); }
510
511/*********************************************************************/
512/* AARCH64_OP_COND */
513
514static inline RasmOp a64op_cond(int cond)
515{
517 op.u8[0] = cond;
518 return op;
519}
520
521static inline uint8_t a64op_cond_val(RasmOp op) { return op.u8[0]; }
522
523static inline RasmOp a64cond_eq(void) { return a64op_cond(AARCH64_COND_EQ); }
524static inline RasmOp a64cond_ne(void) { return a64op_cond(AARCH64_COND_NE); }
525static inline RasmOp a64cond_hs(void) { return a64op_cond(AARCH64_COND_HS); }
526static inline RasmOp a64cond_cs(void) { return a64op_cond(AARCH64_COND_CS); }
527static inline RasmOp a64cond_lo(void) { return a64op_cond(AARCH64_COND_LO); }
528static inline RasmOp a64cond_cc(void) { return a64op_cond(AARCH64_COND_CC); }
529static inline RasmOp a64cond_mi(void) { return a64op_cond(AARCH64_COND_MI); }
530static inline RasmOp a64cond_pl(void) { return a64op_cond(AARCH64_COND_PL); }
531static inline RasmOp a64cond_vs(void) { return a64op_cond(AARCH64_COND_VS); }
532static inline RasmOp a64cond_vc(void) { return a64op_cond(AARCH64_COND_VC); }
533static inline RasmOp a64cond_hi(void) { return a64op_cond(AARCH64_COND_HI); }
534static inline RasmOp a64cond_ls(void) { return a64op_cond(AARCH64_COND_LS); }
535static inline RasmOp a64cond_ge(void) { return a64op_cond(AARCH64_COND_GE); }
536static inline RasmOp a64cond_lt(void) { return a64op_cond(AARCH64_COND_LT); }
537static inline RasmOp a64cond_gt(void) { return a64op_cond(AARCH64_COND_GT); }
538static inline RasmOp a64cond_le(void) { return a64op_cond(AARCH64_COND_LE); }
539static inline RasmOp a64cond_al(void) { return a64op_cond(AARCH64_COND_AL); }
540static inline RasmOp a64cond_nv(void) { return a64op_cond(AARCH64_COND_NV); }
541
542/*********************************************************************/
543/* Helpers to add instructions. */
544
545#define i_none(rctx ) rasm_add_insn(rctx, AARCH64_INSN_NONE, OPN, OPN, OPN, OPN)
546
547#define i_add(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_ADD, op0, op1, op2, OPN)
548#define i_addv(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_ADDV, op0, op1, OPN, OPN)
549#define i_adr(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_ADR, op0, op1, OPN, OPN)
550#define i_and(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_AND, op0, op1, op2, OPN)
551#define i_b(rctx, op0 ) rasm_add_insn(rctx, AARCH64_INSN_B, op0, OPN, OPN, OPN)
552#define i_bcond(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_BCOND, op0, op1, OPN, OPN)
553#define i_blr(rctx, op0 ) rasm_add_insn(rctx, AARCH64_INSN_BLR, op0, OPN, OPN, OPN)
554#define i_br(rctx, op0 ) rasm_add_insn(rctx, AARCH64_INSN_BR, op0, OPN, OPN, OPN)
555#define i_cmp(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_CMP, op0, op1, OPN, OPN)
556#define i_csel(rctx, op0, op1, op2, op3) rasm_add_insn(rctx, AARCH64_INSN_CSEL, op0, op1, op2, op3)
557#define i_dup(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_DUP, op0, op1, OPN, OPN)
558#define i_fadd(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_FADD, op0, op1, op2, OPN)
559#define i_fcvtzu(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_FCVTZU, op0, op1, OPN, OPN)
560#define i_fmax(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_FMAX, op0, op1, op2, OPN)
561#define i_fmin(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_FMIN, op0, op1, op2, OPN)
562#define i_fmla(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_FMLA, op0, op1, op2, OPN)
563#define i_fmul(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_FMUL, op0, op1, op2, OPN)
564#define i_ins(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_INS, op0, op1, OPN, OPN)
565#define i_ld1(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_LD1, op0, op1, OPN, OPN)
566#define i_ld1r(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_LD1R, op0, op1, OPN, OPN)
567#define i_ld2(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_LD2, op0, op1, OPN, OPN)
568#define i_ld3(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_LD3, op0, op1, OPN, OPN)
569#define i_ld4(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_LD4, op0, op1, OPN, OPN)
570#define i_ldp(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_LDP, op0, op1, op2, OPN)
571#define i_ldr(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_LDR, op0, op1, OPN, OPN)
572#define i_ldrb(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_LDRB, op0, op1, OPN, OPN)
573#define i_ldrh(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_LDRH, op0, op1, OPN, OPN)
574#define i_lsr(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_LSR, op0, op1, op2, OPN)
575#define i_mov(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_MOV, op0, op1, OPN, OPN)
576#define i_movi(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_MOVI, op0, op1, OPN, OPN)
577#define i_mul(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_MUL, op0, op1, op2, OPN)
578#define i_orr(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_ORR, op0, op1, op2, OPN)
579#define i_ret(rctx ) rasm_add_insn(rctx, AARCH64_INSN_RET, OPN, OPN, OPN, OPN)
580#define i_rev16(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_REV16, op0, op1, OPN, OPN)
581#define i_rev32(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_REV32, op0, op1, OPN, OPN)
582#define i_shl(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_SHL, op0, op1, op2, OPN)
583#define i_st1(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_ST1, op0, op1, OPN, OPN)
584#define i_st2(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_ST2, op0, op1, OPN, OPN)
585#define i_st3(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_ST3, op0, op1, OPN, OPN)
586#define i_st4(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_ST4, op0, op1, OPN, OPN)
587#define i_stp(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_STP, op0, op1, op2, OPN)
588#define i_str(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_STR, op0, op1, OPN, OPN)
589#define i_sub(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_SUB, op0, op1, op2, OPN)
590#define i_subs(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_SUBS, op0, op1, op2, OPN)
591#define i_tbl(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_TBL, op0, op1, op2, OPN)
592#define i_ubfiz(rctx, op0, op1, op2, op3) rasm_add_insn(rctx, AARCH64_INSN_UBFIZ, op0, op1, op2, op3)
593#define i_ucvtf(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_UCVTF, op0, op1, OPN, OPN)
594#define i_umax(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_UMAX, op0, op1, op2, OPN)
595#define i_umin(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_UMIN, op0, op1, op2, OPN)
596#define i_uqxtn(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_UQXTN, op0, op1, OPN, OPN)
597#define i_ushl(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_USHL, op0, op1, op2, OPN)
598#define i_ushll(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_USHLL, op0, op1, op2, OPN)
599#define i_ushll2(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_USHLL2, op0, op1, op2, OPN)
600#define i_ushr(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_USHR, op0, op1, op2, OPN)
601#define i_uxtl(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_UXTL, op0, op1, OPN, OPN)
602#define i_uxtl2(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_UXTL2, op0, op1, OPN, OPN)
603#define i_xtn(rctx, op0, op1 ) rasm_add_insn(rctx, AARCH64_INSN_XTN, op0, op1, OPN, OPN)
604#define i_zip1(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_ZIP1, op0, op1, op2, OPN)
605#define i_zip2(rctx, op0, op1, op2 ) rasm_add_insn(rctx, AARCH64_INSN_ZIP2, op0, op1, op2, OPN)
606
607/* Branch helpers. */
608#define i_beq(rctx, id) i_bcond(rctx, a64cond_eq(), rasm_op_label(id))
609#define i_bne(rctx, id) i_bcond(rctx, a64cond_ne(), rasm_op_label(id))
610#define i_bhs(rctx, id) i_bcond(rctx, a64cond_hs(), rasm_op_label(id))
611#define i_bcs(rctx, id) i_bcond(rctx, a64cond_cs(), rasm_op_label(id))
612#define i_blo(rctx, id) i_bcond(rctx, a64cond_lo(), rasm_op_label(id))
613#define i_bcc(rctx, id) i_bcond(rctx, a64cond_cc(), rasm_op_label(id))
614#define i_bmi(rctx, id) i_bcond(rctx, a64cond_mi(), rasm_op_label(id))
615#define i_bpl(rctx, id) i_bcond(rctx, a64cond_pl(), rasm_op_label(id))
616#define i_bvs(rctx, id) i_bcond(rctx, a64cond_vs(), rasm_op_label(id))
617#define i_bvc(rctx, id) i_bcond(rctx, a64cond_vc(), rasm_op_label(id))
618#define i_bhi(rctx, id) i_bcond(rctx, a64cond_hi(), rasm_op_label(id))
619#define i_bls(rctx, id) i_bcond(rctx, a64cond_ls(), rasm_op_label(id))
620#define i_bge(rctx, id) i_bcond(rctx, a64cond_ge(), rasm_op_label(id))
621#define i_blt(rctx, id) i_bcond(rctx, a64cond_lt(), rasm_op_label(id))
622#define i_bgt(rctx, id) i_bcond(rctx, a64cond_gt(), rasm_op_label(id))
623#define i_ble(rctx, id) i_bcond(rctx, a64cond_le(), rasm_op_label(id))
624
625/* Extra helpers. */
626#define i_and16b(rctx, op0, op1, op2) i_and(rctx, v_16b(op0), v_16b(op1), v_16b(op2))
627#define i_mov16b(rctx, op0, op1 ) i_mov(rctx, v_16b(op0), v_16b(op1) )
628#define i_orr16b(rctx, op0, op1, op2) i_orr(rctx, v_16b(op0), v_16b(op1), v_16b(op2))
629
630#endif /* SWSCALE_AARCH64_RASM_H */
static double val(void *priv, double ch)
Definition aeval.c:77
int32_t
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
AVBPrint public header.
static int FUNC comment(CodedBitstreamContext *ctx, RWContext *rw, JPEGRawComment *current)
#define s(width, name)
Definition cbs_vp9.c:198
cl_device_type type
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition anm.c:76
Macro definitions for various function/variable attributes.
#define av_printf_format(fmtpos, attrpos)
Definition attributes.h:218
int(* cond)(enum AVPixelFormat pix_fmt)
const char * name
Definition qsvenc.c:142
RasmNode * rasm_get_current_node(RasmContext *rctx)
Definition rasm.c:194
RasmNode * rasm_add_func(RasmContext *rctx, int id, bool export, bool jumpable)
Definition rasm.c:155
void rasm_annotatef(RasmContext *rctx, char *s, size_t n, const char *fmt,...)
Definition rasm.c:254
void rasm_annotate(RasmContext *rctx, const char *comment)
Definition rasm.c:243
RasmNode * rasm_add_directive(RasmContext *rctx, const char *text)
Definition rasm.c:174
int rasm_func_begin(RasmContext *rctx, const char *name, bool export, bool jumpable)
Definition rasm.c:209
RasmNode * rasm_add_label(RasmContext *rctx, int id)
Definition rasm.c:146
RasmNode * rasm_add_endfunc(RasmContext *rctx)
Definition rasm.c:168
int rasm_new_label(RasmContext *rctx, const char *name)
Allocate a new label ID with the given name.
Definition rasm.c:282
void rasm_annotate_next(RasmContext *rctx, const char *comment)
Definition rasm.c:263
int rasm_new_labelf(RasmContext *rctx, char *s, size_t n, const char *fmt,...)
Definition rasm.c:318
RasmNode * rasm_set_current_node(RasmContext *rctx, RasmNode *node)
Definition rasm.c:199
void rasm_annotate_nextf(RasmContext *rctx, char *s, size_t n, const char *fmt,...)
Definition rasm.c:273
RasmNodeType
Definition rasm.h:111
@ RASM_NODE_DIRECTIVE
Definition rasm.h:117
@ RASM_NODE_FUNCTION
Definition rasm.h:115
@ RASM_NODE_DATA
Definition rasm.h:118
@ RASM_NODE_ENDFUNC
Definition rasm.h:116
@ RASM_NODE_LABEL
Definition rasm.h:114
@ RASM_NODE_INSN
Definition rasm.h:112
@ RASM_NODE_COMMENT
Definition rasm.h:113
static RasmOp a64op_lr(void)
Definition rasm.h:356
static RasmOp a64cond_nv(void)
Definition rasm.h:540
#define AARCH64_BASE_PRE
Definition rasm.h:490
static RasmOp a64cond_lo(void)
Definition rasm.h:527
static RasmOp v_2s(RasmOp op)
Definition rasm.h:441
static RasmOp a64op_base(RasmOp op)
Definition rasm.h:506
#define AARCH64_BASE_OFFSET
Definition rasm.h:489
static uint8_t a64op_gpr_n(RasmOp op)
Definition rasm.h:351
static RasmOp a64cond_pl(void)
Definition rasm.h:530
static RasmOp a64op_sp(void)
Definition rasm.h:357
RasmNode * rasm_add_insn(RasmContext *rctx, int id, RasmOp op0, RasmOp op1, RasmOp op2, RasmOp op3)
Definition rasm.c:101
static RasmOp a64cond_cc(void)
Definition rasm.h:528
AArch64VecViews a64op_vec_views(RasmOp op)
Definition rasm.c:330
static RasmOp v_8h(RasmOp op)
Definition rasm.h:440
static RasmOp v_8b(RasmOp op)
Definition rasm.h:437
static int rasm_op_label_id(RasmOp op)
Definition rasm.h:103
static uint8_t a64op_cond_val(RasmOp op)
Definition rasm.h:521
#define AARCH64_COND_MI
Definition rasm.h:327
static RasmOp v_h(RasmOp op)
Definition rasm.h:431
static RasmOp a64cond_cs(void)
Definition rasm.h:526
static uint8_t a64op_gpr_size(RasmOp op)
Definition rasm.h:352
static RasmOp vv_4(RasmOp op0, RasmOp op1, RasmOp op2, RasmOp op3)
Definition rasm.h:449
void rasm_free(RasmContext **prctx)
Definition rasm.c:37
static RasmOp a64op_x(RasmOp op)
Definition rasm.h:361
static RasmOp a64cond_mi(void)
Definition rasm.h:529
static RasmOp a64op_vec(uint8_t n)
Definition rasm.h:383
static RasmOp v_b(RasmOp op)
Definition rasm.h:430
static RasmOp a64cond_ls(void)
Definition rasm.h:534
static RasmOp a64cond_eq(void)
Definition rasm.h:523
static RasmOp a64cond_hi(void)
Definition rasm.h:533
static RasmOp a64cond_le(void)
Definition rasm.h:538
RasmOpType
Definition rasm.h:62
@ RASM_OP_NB
Definition rasm.h:66
@ RASM_OP_LABEL
Definition rasm.h:65
@ RASM_OP_IMM
Definition rasm.h:64
@ RASM_OP_NONE
Definition rasm.h:63
static RasmOp a64cond_vs(void)
Definition rasm.h:531
static RasmOp a64op_make_gpr(uint8_t n, uint8_t size)
Definition rasm.h:343
static RasmOp a64op_vech(uint8_t n)
Definition rasm.h:385
static RasmOp a64op_vecq(uint8_t n)
Definition rasm.h:388
static RasmOp a64op_vec8h(uint8_t n)
Definition rasm.h:392
static RasmOp a64op_veclist(RasmOp op0, RasmOp op1, RasmOp op2, RasmOp op3)
Create register-list operand for structured load/store instructions.
Definition rasm.h:401
static RasmOp a64op_pre(RasmOp op, int16_t imm)
Definition rasm.h:508
#define AARCH64_BASE_POST
Definition rasm.h:491
#define AARCH64_COND_LO
Definition rasm.h:325
static RasmOp a64op_vec2d(uint8_t n)
Definition rasm.h:395
static RasmOp a64op_elem(RasmOp op, uint8_t idx)
Definition rasm.h:422
RasmContext * rasm_alloc(void)
Definition rasm.c:32
static int16_t a64op_base_imm(RasmOp op)
Definition rasm.h:502
static RasmOp a64cond_hs(void)
Definition rasm.h:525
static RasmOp a64op_gpx(uint8_t n)
Definition rasm.h:355
static uint8_t rasm_op_type(RasmOp op)
Definition rasm.h:58
static RasmOp v_4h(RasmOp op)
Definition rasm.h:439
static RasmOp a64cond_vc(void)
Definition rasm.h:532
static uint8_t a64op_base_mode(RasmOp op)
Definition rasm.h:504
static RasmOp v_4s(RasmOp op)
Definition rasm.h:442
static RasmOp rasm_op_new(int type)
Definition rasm.h:51
static RasmOp a64op_make_base(uint8_t n, uint8_t mode, int16_t imm)
Definition rasm.h:493
static uint8_t a64op_vec_num_regs(RasmOp op)
Definition rasm.h:380
static RasmOp v_q(RasmOp op)
Definition rasm.h:434
static RasmOp a64op_vecb(uint8_t n)
Definition rasm.h:384
#define AARCH64_COND_AL
Definition rasm.h:337
static RasmOp a64op_vecd(uint8_t n)
Definition rasm.h:387
static RasmOp a64op_vec2s(uint8_t n)
Definition rasm.h:393
#define AARCH64_COND_NV
Definition rasm.h:338
#define AARCH64_COND_VC
Definition rasm.h:330
static uint8_t a64op_vec_idx_p1(RasmOp op)
Definition rasm.h:381
static int32_t rasm_op_imm_val(RasmOp op)
Definition rasm.h:87
static RasmOp a64op_vec8b(uint8_t n)
Definition rasm.h:389
static RasmOp a64op_off(RasmOp op, int16_t imm)
Definition rasm.h:507
#define AARCH64_COND_EQ
Definition rasm.h:321
static RasmOp rasm_op_label(int id)
Definition rasm.h:96
static RasmOp a64op_vec4h(uint8_t n)
Definition rasm.h:391
static RasmOp vv_2(RasmOp op0, RasmOp op1)
Definition rasm.h:447
static RasmOp v_2d(RasmOp op)
Definition rasm.h:443
static RasmOp v_16b(RasmOp op)
Definition rasm.h:438
static RasmOp a64op_cond(int cond)
Definition rasm.h:514
static RasmOp a64op_post(RasmOp op, int16_t imm)
Definition rasm.h:509
RasmNode * rasm_add_comment(RasmContext *rctx, const char *comment)
Definition rasm.c:117
static uint8_t a64op_vec_n(RasmOp op)
Definition rasm.h:377
static RasmOp a64op_vec4s(uint8_t n)
Definition rasm.h:394
static RasmOp rasm_op_none(void)
Definition rasm.h:71
RasmEntryType
Definition rasm.h:162
@ RASM_ENTRY_FUNC
Definition rasm.h:163
@ RASM_ENTRY_DATA
Definition rasm.h:164
static RasmOp a64op_vec16b(uint8_t n)
Definition rasm.h:390
void int rasm_print(RasmContext *rctx, AVBPrint *bp)
Definition rasm_print.c:422
#define AARCH64_COND_HS
Definition rasm.h:323
#define AARCH64_COND_LE
Definition rasm.h:336
static RasmOp a64op_vecs(uint8_t n)
Definition rasm.h:386
#define AARCH64_COND_GE
Definition rasm.h:333
static RasmOp a64cond_al(void)
Definition rasm.h:539
AArch64OpType
Definition rasm.h:311
@ AARCH64_OP_BASE
Definition rasm.h:314
@ AARCH64_OP_GPR
Definition rasm.h:312
@ AARCH64_OP_COND
Definition rasm.h:315
@ AARCH64_OP_VEC
Definition rasm.h:313
@ AARCH64_OP_NB
Definition rasm.h:317
#define AARCH64_COND_CC
Definition rasm.h:326
static RasmOp a64cond_lt(void)
Definition rasm.h:536
#define AARCH64_COND_NE
Definition rasm.h:322
static RasmOp vv_1(RasmOp op0)
Definition rasm.h:446
#define AARCH64_COND_LT
Definition rasm.h:334
#define AARCH64_COND_PL
Definition rasm.h:328
static RasmOp a64cond_ge(void)
Definition rasm.h:535
static RasmOp a64cond_ne(void)
Definition rasm.h:524
static RasmOp a64cond_gt(void)
Definition rasm.h:537
static uint8_t a64op_base_n(RasmOp op)
Definition rasm.h:503
static RasmOp vv_3(RasmOp op0, RasmOp op1, RasmOp op2)
Definition rasm.h:448
#define OPN
Definition rasm.h:76
static RasmOp rasm_op_imm(int32_t val)
Definition rasm.h:80
static RasmOp a64op_w(RasmOp op)
Definition rasm.h:360
static RasmOp a64op_make_vec(uint8_t n, uint8_t el_count, uint8_t el_size)
Definition rasm.h:366
RasmNode * rasm_add_commentf(RasmContext *rctx, char *s, size_t n, const char *fmt,...) av_printf_format(4
AArch64InsnId
Definition rasm.h:244
@ AARCH64_INSN_UMIN
Definition rasm.h:295
@ AARCH64_INSN_MOVI
Definition rasm.h:276
@ AARCH64_INSN_FMIN
Definition rasm.h:261
@ AARCH64_INSN_LDR
Definition rasm.h:271
@ AARCH64_INSN_UXTL2
Definition rasm.h:302
@ AARCH64_INSN_NB
Definition rasm.h:307
@ AARCH64_INSN_ST4
Definition rasm.h:286
@ AARCH64_INSN_REV16
Definition rasm.h:280
@ AARCH64_INSN_ZIP2
Definition rasm.h:305
@ AARCH64_INSN_BCOND
Definition rasm.h:252
@ AARCH64_INSN_UMAX
Definition rasm.h:294
@ AARCH64_INSN_TBL
Definition rasm.h:291
@ AARCH64_INSN_USHR
Definition rasm.h:300
@ AARCH64_INSN_LDRB
Definition rasm.h:272
@ AARCH64_INSN_B
Definition rasm.h:251
@ AARCH64_INSN_STP
Definition rasm.h:287
@ AARCH64_INSN_ADDV
Definition rasm.h:248
@ AARCH64_INSN_ADR
Definition rasm.h:249
@ AARCH64_INSN_USHL
Definition rasm.h:297
@ AARCH64_INSN_AND
Definition rasm.h:250
@ AARCH64_INSN_ORR
Definition rasm.h:278
@ AARCH64_INSN_SUB
Definition rasm.h:289
@ AARCH64_INSN_REV32
Definition rasm.h:281
@ AARCH64_INSN_UXTL
Definition rasm.h:301
@ AARCH64_INSN_INS
Definition rasm.h:264
@ AARCH64_INSN_NONE
Definition rasm.h:245
@ AARCH64_INSN_ST1
Definition rasm.h:283
@ AARCH64_INSN_FMAX
Definition rasm.h:260
@ AARCH64_INSN_LD1
Definition rasm.h:265
@ AARCH64_INSN_BR
Definition rasm.h:254
@ AARCH64_INSN_ADD
Definition rasm.h:247
@ AARCH64_INSN_SUBS
Definition rasm.h:290
@ AARCH64_INSN_LDP
Definition rasm.h:270
@ AARCH64_INSN_LD1R
Definition rasm.h:266
@ AARCH64_INSN_LD3
Definition rasm.h:268
@ AARCH64_INSN_FCVTZU
Definition rasm.h:259
@ AARCH64_INSN_FADD
Definition rasm.h:258
@ AARCH64_INSN_ST2
Definition rasm.h:284
@ AARCH64_INSN_UBFIZ
Definition rasm.h:292
@ AARCH64_INSN_CSEL
Definition rasm.h:256
@ AARCH64_INSN_CMP
Definition rasm.h:255
@ AARCH64_INSN_LSR
Definition rasm.h:274
@ AARCH64_INSN_LDRH
Definition rasm.h:273
@ AARCH64_INSN_ST3
Definition rasm.h:285
@ AARCH64_INSN_DUP
Definition rasm.h:257
@ AARCH64_INSN_ZIP1
Definition rasm.h:304
@ AARCH64_INSN_BLR
Definition rasm.h:253
@ AARCH64_INSN_STR
Definition rasm.h:288
@ AARCH64_INSN_LD4
Definition rasm.h:269
@ AARCH64_INSN_FMLA
Definition rasm.h:262
@ AARCH64_INSN_UQXTN
Definition rasm.h:296
@ AARCH64_INSN_FMUL
Definition rasm.h:263
@ AARCH64_INSN_RET
Definition rasm.h:279
@ AARCH64_INSN_USHLL2
Definition rasm.h:299
@ AARCH64_INSN_MOV
Definition rasm.h:275
@ AARCH64_INSN_LD2
Definition rasm.h:267
@ AARCH64_INSN_UCVTF
Definition rasm.h:293
@ AARCH64_INSN_USHLL
Definition rasm.h:298
@ AARCH64_INSN_SHL
Definition rasm.h:282
@ AARCH64_INSN_MUL
Definition rasm.h:277
@ AARCH64_INSN_XTN
Definition rasm.h:303
#define AARCH64_COND_LS
Definition rasm.h:332
static RasmOp v_d(RasmOp op)
Definition rasm.h:433
#define AARCH64_COND_VS
Definition rasm.h:329
#define AARCH64_COND_CS
Definition rasm.h:324
#define AARCH64_COND_GT
Definition rasm.h:335
#define AARCH64_COND_HI
Definition rasm.h:331
static uint8_t a64op_vec_el_count(RasmOp op)
Definition rasm.h:378
static uint8_t a64op_vec_el_size(RasmOp op)
Definition rasm.h:379
static RasmOp v_s(RasmOp op)
Definition rasm.h:432
static RasmOp a64op_gpw(uint8_t n)
Definition rasm.h:354
This helper structure is used to mimic the assembler syntax for vector register modifiers.
Definition rasm.h:456
RasmOp d2
Definition rasm.h:470
RasmOp h
Definition rasm.h:459
RasmOp b16
Definition rasm.h:465
RasmOp s2
Definition rasm.h:468
RasmOp be[2]
Definition rasm.h:472
RasmOp d
Definition rasm.h:461
RasmOp b8
Definition rasm.h:464
RasmOp s4
Definition rasm.h:469
RasmOp h4
Definition rasm.h:466
RasmOp q
Definition rasm.h:462
RasmOp de[2]
Definition rasm.h:473
RasmOp b
Definition rasm.h:458
RasmOp h8
Definition rasm.h:467
RasmOp s
Definition rasm.h:460
RasmNode * current_node
Definition rasm.h:190
int num_labels
Definition rasm.h:189
int error
Definition rasm.h:192
char * comment_next
Definition rasm.h:191
int num_entries
Definition rasm.h:187
RasmEntry * entries
Definition rasm.h:186
char ** labels
Definition rasm.h:188
RasmNode * end
Definition rasm.h:176
RasmEntryType type
Definition rasm.h:174
RasmFunction func
Definition rasm.h:178
RasmNode * start
Definition rasm.h:175
bool export
Definition rasm.h:168
int label_id
Definition rasm.h:169
char * text
Definition rasm.h:127
char * text
Definition rasm.h:141
bool export
Definition rasm.h:136
char * name
Definition rasm.h:135
bool jumpable
Definition rasm.h:137
RasmOp op[4]
Definition rasm.h:123
RasmNodeComment comment
Definition rasm.h:149
RasmNodeLabel label
Definition rasm.h:150
RasmNodeType type
Definition rasm.h:146
RasmNodeInsn insn
Definition rasm.h:148
struct RasmNode * next
Definition rasm.h:156
char * inline_comment
Definition rasm.h:154
struct RasmNode * prev
Definition rasm.h:155
RasmNodeFunc func
Definition rasm.h:151
RasmNodeDirective directive
Definition rasm.h:152
Definition swscale.c:71
int size
Runtime assembler for AArch64.
Definition rasm.h:44
uint64_t u64
Definition rasm.h:48
uint32_t u32[2]
Definition rasm.h:47
uint16_t u16[4]
Definition rasm.h:46
uint8_t u8[8]
Definition rasm.h:45
static int export(AVFilterContext *ctx, StreamContext *sc, int input)