1#define FNNAME1(NAME) exec_ ## NAME ## _lane 2#define FNNAME(NAME) FNNAME1 (NAME) 3 4void FNNAME (INSN) (void) 5{ 6 /* vector_res = vqrdmlXh_lane (vector, vector2, vector3, lane), 7 then store the result. */ 8#define TEST_VQRDMLXH_LANE2(INSN, Q, T1, T2, W, N, N2, L, \ 9 CMT) \ 10 Set_Neon_Cumulative_Sat (0, VECT_VAR (vector_res, T1, W, N)); \ 11 VECT_VAR (vector_res, T1, W, N) = \ 12 INSN##Q##_lane_##T2##W (VECT_VAR (vector, T1, W, N), \ 13 VECT_VAR (vector2, T1, W, N), \ 14 VECT_VAR (vector3, T1, W, N2), \ 15 L); \ 16 vst1##Q##_##T2##W (VECT_VAR (result, T1, W, N), \ 17 VECT_VAR (vector_res, T1, W, N)) 18 19 /* Two auxliary macros are necessary to expand INSN. */ 20#define TEST_VQRDMLXH_LANE1(INSN, Q, T1, T2, W, N, N2, L, \ 21 CMT) \ 22 TEST_VQRDMLXH_LANE2 (INSN, Q, T1, T2, W, N, N2, L, \ 23 CMT) 24 25#define TEST_VQRDMLXH_LANE(Q, T1, T2, W, N, N2, L, \ 26 CMT) \ 27 TEST_VQRDMLXH_LANE1 (INSN, Q, T1, T2, W, N, N2, L, \ 28 CMT) 29 30 31 DECL_VARIABLE (vector, int, 16, 4); 32 DECL_VARIABLE (vector, int, 32, 2); 33 DECL_VARIABLE (vector, int, 16, 8); 34 DECL_VARIABLE (vector, int, 32, 4); 35 36 DECL_VARIABLE (vector_res, int, 16, 4); 37 DECL_VARIABLE (vector_res, int, 32, 2); 38 DECL_VARIABLE (vector_res, int, 16, 8); 39 DECL_VARIABLE (vector_res, int, 32, 4); 40 41 DECL_VARIABLE (vector2, int, 16, 4); 42 DECL_VARIABLE (vector2, int, 32, 2); 43 DECL_VARIABLE (vector2, int, 16, 8); 44 DECL_VARIABLE (vector2, int, 32, 4); 45 46 DECL_VARIABLE (vector3, int, 16, 4); 47 DECL_VARIABLE (vector3, int, 32, 2); 48 DECL_VARIABLE (vector3, int, 16, 8); 49 DECL_VARIABLE (vector3, int, 32, 4); 50 51 clean_results (); 52 53 VLOAD (vector, buffer, , int, s, 16, 4); 54 VLOAD (vector, buffer, , int, s, 32, 2); 55 56 VLOAD (vector, buffer, q, int, s, 16, 8); 57 VLOAD (vector, buffer, q, int, s, 32, 4); 58 59 /* Initialize vector2. */ 60 VDUP (vector2, , int, s, 16, 4, 0x5555); 61 VDUP (vector2, , int, s, 32, 2, 0xBB); 62 VDUP (vector2, q, int, s, 16, 8, 0xBB); 63 VDUP (vector2, q, int, s, 32, 4, 0x22); 64 65 /* Initialize vector3. */ 66 VDUP (vector3, , int, s, 16, 4, 0x5555); 67 VDUP (vector3, , int, s, 32, 2, 0xBB); 68 VDUP (vector3, q, int, s, 16, 8, 0x33); 69 VDUP (vector3, q, int, s, 32, 4, 0x22); 70 71 /* Choose lane arbitrarily. */ 72#define CMT "" 73 TEST_VQRDMLXH_LANE (, int, s, 16, 4, 4, 2, CMT); 74 TEST_VQRDMLXH_LANE (, int, s, 32, 2, 2, 1, CMT); 75 TEST_VQRDMLXH_LANE (q, int, s, 16, 8, 4, 3, CMT); 76 TEST_VQRDMLXH_LANE (q, int, s, 32, 4, 2, 0, CMT); 77 78 CHECK (TEST_MSG, int, 16, 4, PRIx16, expected, CMT); 79 CHECK (TEST_MSG, int, 32, 2, PRIx32, expected, CMT); 80 CHECK (TEST_MSG, int, 16, 8, PRIx16, expected, CMT); 81 CHECK (TEST_MSG, int, 32, 4, PRIx32, expected, CMT); 82 83 /* Now use input values such that the multiplication causes 84 saturation. */ 85#define TEST_MSG_MUL " (check mul cumulative saturation)" 86 VDUP (vector, , int, s, 16, 4, 0x8000); 87 VDUP (vector, , int, s, 32, 2, 0x80000000); 88 VDUP (vector, q, int, s, 16, 8, 0x8000); 89 VDUP (vector, q, int, s, 32, 4, 0x80000000); 90 91 VDUP (vector2, , int, s, 16, 4, 0x8000); 92 VDUP (vector2, , int, s, 32, 2, 0x80000000); 93 VDUP (vector2, q, int, s, 16, 8, 0x8000); 94 VDUP (vector2, q, int, s, 32, 4, 0x80000000); 95 96 VDUP (vector3, , int, s, 16, 4, 0x8000); 97 VDUP (vector3, , int, s, 32, 2, 0x80000000); 98 VDUP (vector3, q, int, s, 16, 8, 0x8000); 99 VDUP (vector3, q, int, s, 32, 4, 0x80000000); 100 101 TEST_VQRDMLXH_LANE (, int, s, 16, 4, 4, 2, TEST_MSG_MUL); 102 TEST_VQRDMLXH_LANE (, int, s, 32, 2, 2, 1, TEST_MSG_MUL); 103 TEST_VQRDMLXH_LANE (q, int, s, 16, 8, 4, 3, TEST_MSG_MUL); 104 TEST_VQRDMLXH_LANE (q, int, s, 32, 4, 2, 0, TEST_MSG_MUL); 105 106 CHECK (TEST_MSG, int, 16, 4, PRIx16, expected_mul, TEST_MSG_MUL); 107 CHECK (TEST_MSG, int, 32, 2, PRIx32, expected_mul, TEST_MSG_MUL); 108 CHECK (TEST_MSG, int, 16, 8, PRIx16, expected_mul, TEST_MSG_MUL); 109 CHECK (TEST_MSG, int, 32, 4, PRIx32, expected_mul, TEST_MSG_MUL); 110 111 VDUP (vector, , int, s, 16, 4, 0x8000); 112 VDUP (vector, , int, s, 32, 2, 0x80000000); 113 VDUP (vector, q, int, s, 16, 8, 0x8000); 114 VDUP (vector, q, int, s, 32, 4, 0x80000000); 115 116 VDUP (vector2, , int, s, 16, 4, 0x8001); 117 VDUP (vector2, , int, s, 32, 2, 0x80000001); 118 VDUP (vector2, q, int, s, 16, 8, 0x8001); 119 VDUP (vector2, q, int, s, 32, 4, 0x80000001); 120 121 VDUP (vector3, , int, s, 16, 4, 0x8001); 122 VDUP (vector3, , int, s, 32, 2, 0x80000001); 123 VDUP (vector3, q, int, s, 16, 8, 0x8001); 124 VDUP (vector3, q, int, s, 32, 4, 0x80000001); 125 126 /* Use input values where rounding produces a result equal to the 127 saturation value, but does not set the saturation flag. */ 128#define TEST_MSG_ROUND " (check rounding)" 129 TEST_VQRDMLXH_LANE (, int, s, 16, 4, 4, 2, TEST_MSG_ROUND); 130 TEST_VQRDMLXH_LANE (, int, s, 32, 2, 2, 1, TEST_MSG_ROUND); 131 TEST_VQRDMLXH_LANE (q, int, s, 16, 8, 4, 3, TEST_MSG_ROUND); 132 TEST_VQRDMLXH_LANE (q, int, s, 32, 4, 2, 0, TEST_MSG_ROUND); 133 134 CHECK (TEST_MSG, int, 16, 4, PRIx16, expected_round, TEST_MSG_ROUND); 135 CHECK (TEST_MSG, int, 32, 2, PRIx32, expected_round, TEST_MSG_ROUND); 136 CHECK (TEST_MSG, int, 16, 8, PRIx16, expected_round, TEST_MSG_ROUND); 137 CHECK (TEST_MSG, int, 32, 4, PRIx32, expected_round, TEST_MSG_ROUND); 138} 139 140int 141main (void) 142{ 143 FNNAME (INSN) (); 144 return 0; 145} 146