kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

aa64_inline_test.c (3438B)


      1 /* Public-API unit test for the aarch64 inline-asm backend. */
      2 
      3 #include <stdint.h>
      4 
      5 #include "inline_public_test.h"
      6 
      7 #define EXPECTED_MOV_X1_X5 0xaa0503e1u
      8 #define EXPECTED_NOP 0xd503201fu
      9 #define EXPECTED_ADD_W0_WSP_7 0x11001fe0u
     10 /* System-register move (MRS/MSR register form). TPIDR_EL0 is S3_3_C13_C0_2.
     11  *   MSR TPIDR_EL0, X0 : 0xd51bd040 | Rt   (write, L=0)
     12  *   MRS X1, TPIDR_EL0 : 0xd53bd040 | Rt   (read,  L=1) */
     13 #define EXPECTED_MSR_TPIDR_X0 0xd51bd040u
     14 #define EXPECTED_MRS_X1_TPIDR 0xd53bd041u
     15 
     16 static void put32le(uint8_t out[4], uint32_t v) {
     17   out[0] = (uint8_t)v;
     18   out[1] = (uint8_t)(v >> 8);
     19   out[2] = (uint8_t)(v >> 16);
     20   out[3] = (uint8_t)(v >> 24);
     21 }
     22 
     23 static void aa64_body(KitCompiler* c, KitCg* cg, KitCgTypeId i64_ty) {
     24   KitCgAsmOperand imm;
     25   const char* memory_clobber = "memory";
     26   (void)i64_ty;
     27 
     28   it_inline_asm(c, cg, "mov x1, x5", NULL, 0, NULL, 0, NULL, 0);
     29   it_inline_asm(c, cg, "nop ; nop", NULL, 0, NULL, 0, NULL, 0);
     30   /* System-register thread-pointer access (used by the freestanding cross
     31    * startup stub to seed TPIDR_EL0). */
     32   it_inline_asm(c, cg, "msr tpidr_el0, x0", NULL, 0, NULL, 0, NULL, 0);
     33   it_inline_asm(c, cg, "mrs x1, tpidr_el0", NULL, 0, NULL, 0, NULL, 0);
     34 
     35   kit_cg_push_int(cg, 7, i64_ty);
     36   imm = it_asm_op(c, "i", "imm", i64_ty, KIT_CG_ASM_IN);
     37   it_inline_asm(c, cg, "add w0, wsp, %[imm]", NULL, 0, &imm, 1, &memory_clobber,
     38                 1);
     39 }
     40 
     41 static void aa64_bad_add_zr(KitCompiler* c, KitCg* cg, KitCgTypeId i64_ty) {
     42   (void)i64_ty;
     43   it_inline_asm(c, cg, "add w0, wzr, #7", NULL, 0, NULL, 0, NULL, 0);
     44 }
     45 
     46 static void aa64_bad_ldr_zr(KitCompiler* c, KitCg* cg, KitCgTypeId i64_ty) {
     47   (void)i64_ty;
     48   it_inline_asm(c, cg, "ldr w0, [xzr]", NULL, 0, NULL, 0, NULL, 0);
     49 }
     50 
     51 int main(void) {
     52   InlineTestEnv env;
     53   InlineText text;
     54   uint8_t pat[12];
     55 
     56   it_env_init(&env);
     57   IT_EXPECT(&env,
     58             it_emit_text(&env, KIT_ARCH_ARM_64, "aa64_inline_public", aa64_body,
     59                          &text),
     60             "failed to emit aa64 inline-asm object");
     61   if (text.data) {
     62     put32le(pat, EXPECTED_MOV_X1_X5);
     63     IT_EXPECT(&env, it_contains(text.data, text.len, pat, 4),
     64               "missing mov x1, x5 encoding");
     65 
     66     put32le(pat, EXPECTED_NOP);
     67     put32le(pat + 4, EXPECTED_NOP);
     68     IT_EXPECT(&env, it_contains(text.data, text.len, pat, 8),
     69               "missing two-nop inline asm encoding");
     70 
     71     put32le(pat, EXPECTED_ADD_W0_WSP_7);
     72     IT_EXPECT(&env, it_contains(text.data, text.len, pat, 4),
     73               "missing add w0, wsp, #7 immediate-substitution encoding");
     74 
     75     put32le(pat, EXPECTED_MSR_TPIDR_X0);
     76     IT_EXPECT(&env, it_contains(text.data, text.len, pat, 4),
     77               "missing msr tpidr_el0, x0 encoding");
     78 
     79     put32le(pat, EXPECTED_MRS_X1_TPIDR);
     80     IT_EXPECT(&env, it_contains(text.data, text.len, pat, 4),
     81               "missing mrs x1, tpidr_el0 encoding");
     82   }
     83   it_text_close(&text);
     84 
     85   IT_EXPECT(&env,
     86             it_expect_panic(&env, KIT_ARCH_ARM_64, "aa64_bad_add_zr",
     87                             aa64_bad_add_zr, "zero register"),
     88             "expected add w0, wzr, #7 to panic");
     89   IT_EXPECT(&env,
     90             it_expect_panic(&env, KIT_ARCH_ARM_64, "aa64_bad_ldr_zr",
     91                             aa64_bad_ldr_zr, "zero register"),
     92             "expected ldr w0, [xzr] to panic");
     93 
     94   if (env.fails) {
     95     fprintf(stderr, "%d failure(s)\n", env.fails);
     96     return 1;
     97   }
     98   printf("aa64_inline_test: ok\n");
     99   return 0;
    100 }