rv64_inline_test.c (2463B)
1 /* Public-API unit test for the rv64 inline-asm backend. */ 2 3 #include <stdint.h> 4 5 #include "inline_public_test.h" 6 7 #define ENC_EBREAK 0x00100073u 8 #define ENC_ECALL 0x00000073u 9 #define ENC_NOP 0x00000013u 10 #define ENC_ADDI_T0_T1_42 0x02a30293u 11 #define ENC_FENCE_RW_RW 0x0330000fu 12 13 static void put32le(uint8_t out[4], uint32_t v) { 14 out[0] = (uint8_t)v; 15 out[1] = (uint8_t)(v >> 8); 16 out[2] = (uint8_t)(v >> 16); 17 out[3] = (uint8_t)(v >> 24); 18 } 19 20 static void rv64_body(KitCompiler* c, KitCg* cg, KitCgTypeId i64_ty) { 21 KitCgAsmOperand imm; 22 const char* memory_clobber = "memory"; 23 (void)i64_ty; 24 25 it_inline_asm(c, cg, "ebreak ; ecall", NULL, 0, NULL, 0, NULL, 0); 26 it_inline_asm(c, cg, "nop\nnop", NULL, 0, NULL, 0, NULL, 0); 27 28 kit_cg_push_int(cg, 42, i64_ty); 29 imm = it_asm_op(c, "i", "imm", i64_ty, KIT_CG_ASM_IN); 30 it_inline_asm(c, cg, "addi t0, t1, %[imm]", NULL, 0, &imm, 1, NULL, 0); 31 32 it_inline_asm(c, cg, "fence rw, rw", NULL, 0, NULL, 0, &memory_clobber, 1); 33 } 34 35 static void rv64_bad_operand(KitCompiler* c, KitCg* cg, KitCgTypeId i64_ty) { 36 (void)i64_ty; 37 it_inline_asm(c, cg, "mv %9, a0", NULL, 0, NULL, 0, NULL, 0); 38 } 39 40 int main(void) { 41 InlineTestEnv env; 42 InlineText text; 43 uint8_t pat[12]; 44 45 it_env_init(&env); 46 IT_EXPECT( 47 &env, 48 it_emit_text(&env, KIT_ARCH_RV64, "rv64_inline_public", rv64_body, &text), 49 "failed to emit rv64 inline-asm object"); 50 if (text.data) { 51 put32le(pat, ENC_EBREAK); 52 put32le(pat + 4, ENC_ECALL); 53 IT_EXPECT(&env, it_contains(text.data, text.len, pat, 8), 54 "missing ebreak/ecall encoding"); 55 56 put32le(pat, ENC_NOP); 57 put32le(pat + 4, ENC_NOP); 58 IT_EXPECT(&env, it_contains(text.data, text.len, pat, 8), 59 "missing two-nop inline asm encoding"); 60 61 put32le(pat, ENC_ADDI_T0_T1_42); 62 IT_EXPECT(&env, it_contains(text.data, text.len, pat, 4), 63 "missing addi t0, t1, 42 immediate-substitution encoding"); 64 65 put32le(pat, ENC_FENCE_RW_RW); 66 IT_EXPECT(&env, it_contains(text.data, text.len, pat, 4), 67 "missing fence rw, rw encoding"); 68 } 69 it_text_close(&text); 70 71 IT_EXPECT(&env, 72 it_expect_panic(&env, KIT_ARCH_RV64, "rv64_bad_operand", 73 rv64_bad_operand, "operand index"), 74 "expected out-of-range rv64 asm operand to panic"); 75 76 if (env.fails) { 77 fprintf(stderr, "%d failure(s)\n", env.fails); 78 return 1; 79 } 80 printf("rv64_inline_test: ok\n"); 81 return 0; 82 }