13
13
#include <asm/insn-def.h>
14
14
15
15
#ifndef __ASSEMBLY__
16
- /*
17
- * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
18
- * Section C3.1 "A64 instruction index by encoding":
19
- * AArch64 main encoding table
20
- * Bit position
21
- * 28 27 26 25 Encoding Group
22
- * 0 0 - - Unallocated
23
- * 1 0 0 - Data processing, immediate
24
- * 1 0 1 - Branch, exception generation and system instructions
25
- * - 1 - 0 Loads and stores
26
- * - 1 0 1 Data processing - register
27
- * 0 1 1 1 Data processing - SIMD and floating point
28
- * 1 1 1 1 Data processing - SIMD and floating point
29
- * "-" means "don't care"
30
- */
31
- enum aarch64_insn_encoding_class {
32
- AARCH64_INSN_CLS_UNKNOWN , /* UNALLOCATED */
33
- AARCH64_INSN_CLS_SVE , /* SVE instructions */
34
- AARCH64_INSN_CLS_DP_IMM , /* Data processing - immediate */
35
- AARCH64_INSN_CLS_DP_REG , /* Data processing - register */
36
- AARCH64_INSN_CLS_DP_FPSIMD , /* Data processing - SIMD and FP */
37
- AARCH64_INSN_CLS_LDST , /* Loads and stores */
38
- AARCH64_INSN_CLS_BR_SYS , /* Branch, exception generation and
39
- * system instructions */
40
- };
41
16
42
17
enum aarch64_insn_hint_cr_op {
43
18
AARCH64_INSN_HINT_NOP = 0x0 << 5 ,
@@ -326,6 +301,23 @@ static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
326
301
return (val); \
327
302
}
328
303
304
+ /*
305
+ * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
306
+ * Section C3.1 "A64 instruction index by encoding":
307
+ * AArch64 main encoding table
308
+ * Bit position
309
+ * 28 27 26 25 Encoding Group
310
+ * 0 0 - - Unallocated
311
+ * 1 0 0 - Data processing, immediate
312
+ * 1 0 1 - Branch, exception generation and system instructions
313
+ * - 1 - 0 Loads and stores
314
+ * - 1 0 1 Data processing - register
315
+ * 0 1 1 1 Data processing - SIMD and floating point
316
+ * 1 1 1 1 Data processing - SIMD and floating point
317
+ * "-" means "don't care"
318
+ */
319
+ __AARCH64_INSN_FUNCS (class_branch_sys , 0x1c000000 , 0x14000000 )
320
+
329
321
__AARCH64_INSN_FUNCS (adr , 0x9F000000 , 0x10000000 )
330
322
__AARCH64_INSN_FUNCS (adrp , 0x9F000000 , 0x90000000 )
331
323
__AARCH64_INSN_FUNCS (prfm , 0x3FC00000 , 0x39800000 )
@@ -431,58 +423,122 @@ __AARCH64_INSN_FUNCS(pssbb, 0xFFFFFFFF, 0xD503349F)
431
423
432
424
#undef __AARCH64_INSN_FUNCS
433
425
434
- bool aarch64_insn_is_steppable_hint (u32 insn );
435
- bool aarch64_insn_is_branch_imm (u32 insn );
426
+ static __always_inline bool aarch64_insn_is_steppable_hint (u32 insn )
427
+ {
428
+ if (!aarch64_insn_is_hint (insn ))
429
+ return false;
430
+
431
+ switch (insn & 0xFE0 ) {
432
+ case AARCH64_INSN_HINT_XPACLRI :
433
+ case AARCH64_INSN_HINT_PACIA_1716 :
434
+ case AARCH64_INSN_HINT_PACIB_1716 :
435
+ case AARCH64_INSN_HINT_PACIAZ :
436
+ case AARCH64_INSN_HINT_PACIASP :
437
+ case AARCH64_INSN_HINT_PACIBZ :
438
+ case AARCH64_INSN_HINT_PACIBSP :
439
+ case AARCH64_INSN_HINT_BTI :
440
+ case AARCH64_INSN_HINT_BTIC :
441
+ case AARCH64_INSN_HINT_BTIJ :
442
+ case AARCH64_INSN_HINT_BTIJC :
443
+ case AARCH64_INSN_HINT_NOP :
444
+ return true;
445
+ default :
446
+ return false;
447
+ }
448
+ }
449
+
450
+ static __always_inline bool aarch64_insn_is_branch (u32 insn )
451
+ {
452
+ /* b, bl, cb*, tb*, ret*, b.cond, br*, blr* */
453
+
454
+ return aarch64_insn_is_b (insn ) ||
455
+ aarch64_insn_is_bl (insn ) ||
456
+ aarch64_insn_is_cbz (insn ) ||
457
+ aarch64_insn_is_cbnz (insn ) ||
458
+ aarch64_insn_is_tbz (insn ) ||
459
+ aarch64_insn_is_tbnz (insn ) ||
460
+ aarch64_insn_is_ret (insn ) ||
461
+ aarch64_insn_is_ret_auth (insn ) ||
462
+ aarch64_insn_is_br (insn ) ||
463
+ aarch64_insn_is_br_auth (insn ) ||
464
+ aarch64_insn_is_blr (insn ) ||
465
+ aarch64_insn_is_blr_auth (insn ) ||
466
+ aarch64_insn_is_bcond (insn );
467
+ }
436
468
437
- static inline bool aarch64_insn_is_adr_adrp (u32 insn )
469
+ static __always_inline bool aarch64_insn_is_branch_imm (u32 insn )
438
470
{
439
- return aarch64_insn_is_adr (insn ) || aarch64_insn_is_adrp (insn );
471
+ return aarch64_insn_is_b (insn ) ||
472
+ aarch64_insn_is_bl (insn ) ||
473
+ aarch64_insn_is_tbz (insn ) ||
474
+ aarch64_insn_is_tbnz (insn ) ||
475
+ aarch64_insn_is_cbz (insn ) ||
476
+ aarch64_insn_is_cbnz (insn ) ||
477
+ aarch64_insn_is_bcond (insn );
440
478
}
441
479
442
- static inline bool aarch64_insn_is_dsb (u32 insn )
480
+ static __always_inline bool aarch64_insn_is_adr_adrp (u32 insn )
443
481
{
444
- return aarch64_insn_is_dsb_base (insn ) || aarch64_insn_is_dsb_nxs (insn );
482
+ return aarch64_insn_is_adr (insn ) ||
483
+ aarch64_insn_is_adrp (insn );
445
484
}
446
485
447
- static inline bool aarch64_insn_is_barrier (u32 insn )
486
+ static __always_inline bool aarch64_insn_is_dsb (u32 insn )
448
487
{
449
- return aarch64_insn_is_dmb (insn ) || aarch64_insn_is_dsb (insn ) ||
450
- aarch64_insn_is_isb (insn ) || aarch64_insn_is_sb (insn ) ||
451
- aarch64_insn_is_clrex (insn ) || aarch64_insn_is_ssbb (insn ) ||
488
+ return aarch64_insn_is_dsb_base (insn ) ||
489
+ aarch64_insn_is_dsb_nxs (insn );
490
+ }
491
+
492
+ static __always_inline bool aarch64_insn_is_barrier (u32 insn )
493
+ {
494
+ return aarch64_insn_is_dmb (insn ) ||
495
+ aarch64_insn_is_dsb (insn ) ||
496
+ aarch64_insn_is_isb (insn ) ||
497
+ aarch64_insn_is_sb (insn ) ||
498
+ aarch64_insn_is_clrex (insn ) ||
499
+ aarch64_insn_is_ssbb (insn ) ||
452
500
aarch64_insn_is_pssbb (insn );
453
501
}
454
502
455
- static inline bool aarch64_insn_is_store_single (u32 insn )
503
+ static __always_inline bool aarch64_insn_is_store_single (u32 insn )
456
504
{
457
505
return aarch64_insn_is_store_imm (insn ) ||
458
506
aarch64_insn_is_store_pre (insn ) ||
459
507
aarch64_insn_is_store_post (insn );
460
508
}
461
509
462
- static inline bool aarch64_insn_is_store_pair (u32 insn )
510
+ static __always_inline bool aarch64_insn_is_store_pair (u32 insn )
463
511
{
464
512
return aarch64_insn_is_stp (insn ) ||
465
513
aarch64_insn_is_stp_pre (insn ) ||
466
514
aarch64_insn_is_stp_post (insn );
467
515
}
468
516
469
- static inline bool aarch64_insn_is_load_single (u32 insn )
517
+ static __always_inline bool aarch64_insn_is_load_single (u32 insn )
470
518
{
471
519
return aarch64_insn_is_load_imm (insn ) ||
472
520
aarch64_insn_is_load_pre (insn ) ||
473
521
aarch64_insn_is_load_post (insn );
474
522
}
475
523
476
- static inline bool aarch64_insn_is_load_pair (u32 insn )
524
+ static __always_inline bool aarch64_insn_is_load_pair (u32 insn )
477
525
{
478
526
return aarch64_insn_is_ldp (insn ) ||
479
527
aarch64_insn_is_ldp_pre (insn ) ||
480
528
aarch64_insn_is_ldp_post (insn );
481
529
}
482
530
531
+ static __always_inline bool aarch64_insn_uses_literal (u32 insn )
532
+ {
533
+ /* ldr/ldrsw (literal), prfm */
534
+
535
+ return aarch64_insn_is_ldr_lit (insn ) ||
536
+ aarch64_insn_is_ldrsw_lit (insn ) ||
537
+ aarch64_insn_is_adr_adrp (insn ) ||
538
+ aarch64_insn_is_prfm_lit (insn );
539
+ }
540
+
483
541
enum aarch64_insn_encoding_class aarch64_get_insn_class (u32 insn );
484
- bool aarch64_insn_uses_literal (u32 insn );
485
- bool aarch64_insn_is_branch (u32 insn );
486
542
u64 aarch64_insn_decode_immediate (enum aarch64_insn_imm_type type , u32 insn );
487
543
u32 aarch64_insn_encode_immediate (enum aarch64_insn_imm_type type ,
488
544
u32 insn , u64 imm );
@@ -496,8 +552,18 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
496
552
enum aarch64_insn_branch_type type );
497
553
u32 aarch64_insn_gen_cond_branch_imm (unsigned long pc , unsigned long addr ,
498
554
enum aarch64_insn_condition cond );
499
- u32 aarch64_insn_gen_hint (enum aarch64_insn_hint_cr_op op );
500
- u32 aarch64_insn_gen_nop (void );
555
+
556
+ static __always_inline u32
557
+ aarch64_insn_gen_hint (enum aarch64_insn_hint_cr_op op )
558
+ {
559
+ return aarch64_insn_get_hint_value () | op ;
560
+ }
561
+
562
+ static __always_inline u32 aarch64_insn_gen_nop (void )
563
+ {
564
+ return aarch64_insn_gen_hint (AARCH64_INSN_HINT_NOP );
565
+ }
566
+
501
567
u32 aarch64_insn_gen_branch_reg (enum aarch64_insn_register reg ,
502
568
enum aarch64_insn_branch_type type );
503
569
u32 aarch64_insn_gen_load_store_reg (enum aarch64_insn_register reg ,
@@ -580,10 +646,6 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
580
646
enum aarch64_insn_register Rn ,
581
647
enum aarch64_insn_register Rd ,
582
648
u8 lsb );
583
- u32 aarch64_insn_gen_prefetch (enum aarch64_insn_register base ,
584
- enum aarch64_insn_prfm_type type ,
585
- enum aarch64_insn_prfm_target target ,
586
- enum aarch64_insn_prfm_policy policy );
587
649
#ifdef CONFIG_ARM64_LSE_ATOMICS
588
650
u32 aarch64_insn_gen_atomic_ld_op (enum aarch64_insn_register result ,
589
651
enum aarch64_insn_register address ,
0 commit comments