1a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 2a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes/* 3a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesgcc -g -o v8memory_a -march=armv8-a -mfpu=crypto-neon-fp-armv8 \ 4a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes none/tests/arm/v8memory.c -I. -Wall -marm 5a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 6a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesgcc -g -o v8memory_t -march=armv8-a -mfpu=crypto-neon-fp-armv8 \ 7a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes none/tests/arm/v8memory.c -I. -Wall -mthumb 8a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes*/ 9a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 10a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes/* These tests unfortunately are unable to check the relative 11a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes placement (or, even, presence) of the required memory fences 12a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes relative to the store/load required. They only verify the 13a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes data-movement component. */ 14a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 15a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#include <stdio.h> 16a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#include <malloc.h> // memalign 17a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#include <string.h> // memset 18a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#include "tests/malloc.h" 19a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#include <assert.h> 20a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 21a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef unsigned char UChar; 22a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef unsigned short int UShort; 23a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef unsigned int UInt; 24a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef signed int Int; 25a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef unsigned char UChar; 26a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef signed long long int Long; 27a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef unsigned long long int ULong; 28a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 29a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughestypedef unsigned char Bool; 30a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define False ((Bool)0) 31a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define True ((Bool)1) 32a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 33a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic inline UChar randUChar ( void ) 34a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 35a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes static UInt seed = 90210; // Somewhere in Beverly Hills, allegedly. 36a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes seed = 1103515245 * seed + 12345; 37a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return (seed >> 17) & 0xFF; 38a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 39a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 40a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic UInt randUInt ( void ) 41a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 42a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes Int i; 43a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes UInt r = 0; 44a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (i = 0; i < 4; i++) { 45a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes r = (r << 8) | (UInt)(0xFF & randUChar()); 46a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 47a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return r; 48a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 49a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 50a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic void show_block_xor ( UChar* block1, UChar* block2, Int n ) 51a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 52a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes Int i; 53a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf(" "); 54a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (i = 0; i < n; i++) { 55a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (i > 0 && 0 == (i & 15)) printf("\n "); 56a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (0 == (i & 15)) printf("[%3d] ", i); 57a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes UInt diff = 0xFF & (UInt)(block1[i] - block2[i]); 58a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (diff == 0) 59a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf(".. "); 60a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes else 61a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%02x ", diff); 62a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 63a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("\n"); 64a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 65a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 66a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 67a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// INSN may mention the following regs as containing load/store data: 68a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// r2 r3 r6 r9 69a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// INSN must mention the following reg as containing the EA: r10 70a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// 71a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// INSN can use r4 and r5 as scratch 72a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// 73a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// In: rand: memory area (128 bytes), r2, r3, r6, r9 74a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// r10 pointing to middle of memory area 75a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// 76a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// Out: memory area, r2, r3, r6, r9, r10 77a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// 78a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// What is printed out: the XOR of the new and old versions of the 79a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// following: 80a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// the memory area 81a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes// r2, r3 r6 r9 r10 82a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 83a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes#define MEM_TEST(INSN) { \ 84a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes int i; \ 85a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes const int N = 128; \ 86a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes UChar* area1 = memalign16(N); \ 87a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes UChar* area2 = memalign16(N); \ 88a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (i = 0; i < N; i++) area1[i] = area2[i] = randUChar(); \ 89a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes UInt block1[5]; \ 90a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes UInt block2[5]; \ 91a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* 0:r2 1:r3 2:r6 3:r9 4:r10 */ \ 92a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes for (i = 0; i < 5; i++) block1[i] = block2[i] = randUInt(); \ 93a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes block1[4] = block2[4] = (UInt)(&area1[N/2]); \ 94a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes __asm__ __volatile__( \ 95a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "ldr r2, [%0, #0] ; " \ 96a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "ldr r3, [%0, #4] ; " \ 97a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "ldr r6, [%0, #8] ; " \ 98a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "ldr r9, [%0, #12] ; " \ 99a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "ldr r10, [%0, #16] ; " \ 100a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes INSN " ; " \ 101a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "str r2, [%0, #0] ; " \ 102a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "str r3, [%0, #4] ; " \ 103a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "str r6, [%0, #8] ; " \ 104a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "str r9, [%0, #12] ; " \ 105a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "str r10, [%0, #16] ; " \ 106a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes : : "r"(&block1[0]) : "r2", "r3", "r4", "r5", "r6", "r9", "r10", \ 107a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "memory", "cc" \ 108a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes ); \ 109a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("%s with r10 = middle_of_block\n", INSN); \ 110a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes show_block_xor(&area1[0], &area2[0], N); \ 111a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf(" %08x r2 (xor, data intreg #1)\n", block1[0] ^ block2[0]); \ 112a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf(" %08x r3 (xor, data intreg #2)\n", block1[1] ^ block2[1]); \ 113a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf(" %08x r6 (xor, data intreg #3)\n", block1[2] ^ block2[2]); \ 114a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf(" %08x r9 (xor, data intreg #4)\n", block1[3] ^ block2[3]); \ 115a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf(" %08x r10 (xor, addr intreg #1)\n", block1[4] ^ block2[4]); \ 116a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("\n"); \ 117a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes free(area1); free(area2); \ 118a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 119a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 120a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 121a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesint main ( void ) 122a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes{ 123a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes //////////////////////////////////////////////////////////////// 124a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("LDA{,B,H} (reg)\n\n"); 125a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("lda r6, [r10]") 126a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("ldab r9, [r10]") 127a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("ldah r3, [r10]") 128a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 129a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes //////////////////////////////////////////////////////////////// 130a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("STL{,B,H} (reg)\n\n"); 131a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("stl r6, [r10]") 132a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("stlb r9, [r10]") 133a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("stlh r3, [r10]") 134a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 135a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes //////////////////////////////////////////////////////////////// 136a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("LDAEX{,B,H,D} (reg)\n\n"); 137a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("ldaex r6, [r10]") 138a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("ldaexb r9, [r10]") 139a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("ldaexh r3, [r10]") 140a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("ldaexd r2, r3, [r10]") 141a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 142a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes //////////////////////////////////////////////////////////////// 143a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // These verify that stlex* do notice a cleared (missing) reservation. 144a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("STLEX{,B,H,D} (reg) -- expected to fail\n\n"); 145a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("clrex; stlex r9, r6, [r10]") 146a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("clrex; stlexb r9, r6, [r10]") 147a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("clrex; stlexh r9, r3, [r10]") 148a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("clrex; stlexd r9, r2, r3, [r10]") 149a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 150a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes //////////////////////////////////////////////////////////////// 151a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // These verify that stlex* do notice a successful reservation. 152a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // By using ldaex* to create the reservation in the first place, 153a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes // they also verify that ldaex* actually create a reservation. 154a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes printf("STLEX{,B,H,D} (reg) -- expected to succeed\n\n"); 155a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("ldaex r2, [r10] ; stlex r9, r6, [r10]") 156a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("ldaexb r2, [r10] ; stlexb r9, r6, [r10]") 157a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("ldaexh r2, [r10] ; stlexh r9, r3, [r10]") 158a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes MEM_TEST("mov r4, r2 ; mov r5, r3 ; " // preserve r2/r3 around the ldrexd 159a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "ldaexd r2, r3, [r10] ; " 160a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "mov r2, r4 ; mov r3, r5 ; " 161a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes "stlexd r9, r2, r3, [r10]") 162a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 163a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes return 0; 164a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes} 165