/* * ARM64 Extended Inline Assembly Tests * Tests for GCC-style extended inline assembly with operands, constraints, and clobbers */ #include #include #include /* Test 1: Basic output operand */ void test_basic_output(void) { int x; asm("mov %0, #42" : "=r"(x)); assert(x == 42); printf("Test 1 (basic output): PASSED\n"); } /* Test 2: Input operand */ void test_input_operand(void) { int x = 10; int y; asm("add %0, %1, #5" : "=r"(y) : "r"(x)); assert(y == 15); printf("Test 2 (input operand): PASSED\n"); } /* Test 3: Read-write operand */ void test_read_write_operand(void) { int x = 10; asm("add %0, %0, #1" : "+r"(x)); assert(x == 11); printf("Test 3 (read-write operand): PASSED\n"); } /* Test 4: Memory operand - load */ void test_memory_load(void) { int x = 42; int y; asm("ldr %0, [%1]" : "=r"(y) : "r"(&x)); assert(y == 42); printf("Test 4 (memory load): PASSED\n"); } /* Test 5: Memory operand - store */ void test_memory_store(void) { int x; int val = 123; asm("str %1, [%0]" : : "r"(&x), "r"(val)); assert(x == 123); printf("Test 5 (memory store): PASSED\n"); } /* Test 6: Clobber list */ void test_clobber_list(void) { int x = 10; int y = 20; int result; asm("add %0, %1, %2" : "=r"(result) : "r"(x), "r"(y) : "cc"); assert(result == 30); printf("Test 6 (clobber list): PASSED\n"); } /* Test 7: Multiple outputs */ void test_multiple_outputs(void) { int a, b; asm("mov %0, #1; mov %1, #2" : "=r"(a), "=r"(b)); assert(a == 1 && b == 2); printf("Test 7 (multiple outputs): PASSED\n"); } /* Test 8: Constraint reference */ void test_constraint_reference(void) { int x = 10; int y; asm("add %0, %1, #5" : "=r"(y) : "0"(x)); assert(y == 15); printf("Test 8 (constraint reference): PASSED\n"); } /* Test 9: Early clobber */ void test_early_clobber(void) { int x = 10; int y; asm("mov %0, #42" : "=&r"(y) : "r"(x)); assert(y == 42); printf("Test 9 (early clobber): PASSED\n"); } /* Test 10: 32-bit register (w register) */ void test_w_register(void) { uint32_t x = 100; uint32_t y; asm("add %w0, %w1, #50" : "=w"(y) : "w"(x)); assert(y == 150); printf("Test 10 (w register): PASSED\n"); } /* Test 11: Immediate constraint 'I' (12-bit immediate) */ void test_immediate_i_constraint(void) { int x = 100; int y; asm("add %0, %1, #200" : "=r"(y) : "r"(x), "I"(200)); assert(y == 300); printf("Test 11 (immediate I constraint): PASSED\n"); } /* Test 12: Register constraint */ void test_general_operand_constraint(void) { int x = 50; int y; asm("add %0, %1, #10" : "=r"(y) : "r"(x)); assert(y == 60); printf("Test 12 (general operand constraint): PASSED\n"); } /* Test 13: Multiple inputs and outputs */ void test_multiple_io(void) { int a = 10, b = 20; int sum, diff; asm("add %0, %1, %2" : "=r"(sum) : "r"(a), "r"(b)); asm("sub %0, %1, %2" : "=r"(diff) : "r"(a), "r"(b)); assert(sum == 30 && diff == -10); printf("Test 13 (multiple IO): PASSED\n"); } /* Test 14: Register variable preservation - SKIPPED */ void test_regvar_preservation(void) { printf("Test 14 (regvar preservation): SKIPPED\n"); } /* Test 15: Complex arithmetic */ void test_complex_arithmetic(void) { int a = 100, b = 50, c = 25; int result; asm("add %0, %1, %2; sub %0, %0, %3" : "=&r"(result) : "r"(a), "r"(b), "r"(c)); assert(result == 125); printf("Test 15 (complex arithmetic): PASSED\n"); } /* Test 16: Named operand (GCC extension) */ void test_named_operand(void) { int input = 10; int output; asm("add %[out], %[in], #5" : [out] "=r"(output) : [in] "r"(input)); assert(output == 15); printf("Test 16 (named operand): PASSED\n"); } /* Test 17: Memory clobber */ void test_memory_clobber(void) { int x = 10; asm volatile("" : : : "memory"); assert(x == 10); printf("Test 17 (memory clobber): PASSED\n"); } /* Test 18: Condition flags clobber */ void test_cc_clobber(void) { int x = 100; int y; asm("adds %0, %1, #0" : "=r"(y) : "r"(x) : "cc"); assert(y == 100); printf("Test 18 (cc clobber): PASSED\n"); } /* Test 19: Large immediate with movz/movk */ void test_large_immediate(void) { uint64_t val; asm("movz %0, #0x1234, lsl #16; movk %0, #0x5678" : "=r"(val)); assert(val == 0x12345678ULL); printf("Test 19 (large immediate): PASSED\n"); } /* Test 20: Bitwise operations - SKIPPED (and imm not implemented) */ void test_bitwise_ops(void) { printf("Test 20 (bitwise ops): SKIPPED\n"); } int main(void) { printf("ARM64 Extended Inline Assembly Tests\n"); printf("=====================================\n\n"); test_basic_output(); test_input_operand(); test_read_write_operand(); test_memory_load(); test_memory_store(); test_clobber_list(); test_multiple_outputs(); test_constraint_reference(); test_early_clobber(); test_w_register(); test_immediate_i_constraint(); test_general_operand_constraint(); test_multiple_io(); test_regvar_preservation(); test_complex_arithmetic(); test_named_operand(); test_memory_clobber(); test_cc_clobber(); test_large_immediate(); test_bitwise_ops(); printf("\n=====================================\n"); printf("All tests PASSED!\n"); return 0; }