1 /*
2 * Copyright (c) 2005 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD: stable/9/tools/regression/ia64/unaligned/test.c 140922 2005-01-28 02:58:32Z marcel $
27 */
28
29 #include <machine/float.h>
30 #include <string.h>
31
32 /* Memory accesses. */
33 #define Load 0x01
34 #define Store 0x02
35
36 /* Data type. */
37 #define Integer 0x11
38 #define FloatingPoint 0x12
39
40 /* Data size. */
41 #define Small 0x21
42 #define Medium 0x22
43 #define Large 0x23
44
45 /* Post increment. */
46 #define NoPostInc 0x31
47 #define MinConstPostInc 0x32
48 #define PlusConstPostInc 0x33
49 #define ScratchRegPostInc 0x34
50 #define PreservedRegPostInc 0x35
51
52 #if ACCESS == 0 || TYPE == 0 || SIZE == 0 || POSTINC == 0
53 #error define ACCESS, TYPE, SIZE and/or POSTINC
54 #endif
55
56 #if TYPE == Integer
57 # define REG "r8"
58 # if SIZE == Small
59 # define DATA_TYPE short
60 # define DATA_VALUE 0x1234
61 # define LD "ld2"
62 # define ST "st2"
63 # elif SIZE == Medium
64 # define DATA_TYPE int
65 # define DATA_VALUE 0x12345678
66 # define LD "ld4"
67 # define ST "st4"
68 # elif SIZE == Large
69 # define DATA_TYPE long
70 # define DATA_VALUE 0x1234567890ABCDEF
71 # define LD "ld8"
72 # define ST "st8"
73 # endif
74 #elif TYPE == FloatingPoint
75 # define REG "f6"
76 # if SIZE == Small
77 # define DATA_TYPE float
78 # define DATA_VALUE FLT_MIN
79 # define LD "ldfs"
80 # define ST "stfs"
81 # elif SIZE == Medium
82 # define DATA_TYPE double
83 # define DATA_VALUE DBL_MIN
84 # define LD "ldfd"
85 # define ST "stfd"
86 # elif SIZE == Large
87 # define DATA_TYPE long double
88 # define DATA_VALUE LDBL_MIN
89 # define LD "ldfe"
90 # define ST "stfe"
91 # endif
92 #endif
93
94 struct {
95 DATA_TYPE aligned;
96 char _;
97 char misaligned[sizeof(DATA_TYPE)];
98 } data;
99
100 DATA_TYPE *aligned = &data.aligned;
101 DATA_TYPE *misaligned = (DATA_TYPE *)data.misaligned;
102 DATA_TYPE value = DATA_VALUE;
103
104 void
block_copy(void * dst,void * src,size_t sz)105 block_copy(void *dst, void *src, size_t sz)
106 {
107
108 memcpy(dst, src, sz);
109 }
110
111 int
main()112 main()
113 {
114
115 /* Set PSR.ac. */
116 asm volatile("sum 8");
117
118 #if ACCESS == Load
119 /*
120 * LOAD
121 */
122 block_copy(misaligned, &value, sizeof(DATA_TYPE));
123
124 # if POSTINC == NoPostInc
125 /* Misaligned load. */
126 *aligned = *misaligned;
127 # elif POSTINC == MinConstPostInc
128 asm volatile(
129 "ld8 r2=%0;;"
130 LD " " REG "=[r2],%2;;"
131 "st8 %0=r2;" ST " %1=" REG ";;"
132 : "=m"(misaligned), "=m"(*aligned)
133 : "i"(-sizeof(DATA_TYPE))
134 : REG, "r2", "memory");
135 # elif POSTINC == PlusConstPostInc
136 asm volatile(
137 "ld8 r2=%0;;"
138 LD " " REG "=[r2],%2;;"
139 "st8 %0=r2;" ST " %1=" REG ";;"
140 : "=m"(misaligned), "=m"(*aligned)
141 : "i"(sizeof(DATA_TYPE))
142 : REG, "r2", "memory");
143 # elif POSTINC == ScratchRegPostInc
144 asm volatile(
145 "ld8 r2=%0; mov r3=%2;;"
146 LD " " REG "=[r2],r3;;"
147 "st8 %0=r2;" ST " %1=" REG ";;"
148 : "=m"(misaligned), "=m"(*aligned)
149 : "i"(sizeof(DATA_TYPE))
150 : REG, "r2", "r3", "memory");
151 # elif POSTINC == PreservedRegPostInc
152 asm volatile(
153 "ld8 r2=%0; mov r4=%2;;"
154 LD " " REG "=[r2],r4;;"
155 "st8 %0=r2;" ST " %1=" REG ";;"
156 : "=m"(misaligned), "=m"(*aligned)
157 : "i"(sizeof(DATA_TYPE))
158 : REG, "r2", "r4", "memory");
159 # endif
160
161 #elif ACCESS == Store
162 /*
163 * STORE
164 */
165
166 # if POSTINC == NoPostInc
167 /* Misaligned store. */
168 *misaligned = value;
169 # elif POSTINC == MinConstPostInc
170 asm volatile(
171 "ld8 r2=%0;" LD " " REG "=%1;;"
172 ST " [r2]=" REG ",%2;;"
173 "st8 %0=r2;;"
174 : "=m"(misaligned)
175 : "m"(value), "i"(-sizeof(DATA_TYPE))
176 : REG, "r2", "memory");
177 # elif POSTINC == PlusConstPostInc
178 asm volatile(
179 "ld8 r2=%0;" LD " " REG "=%1;;"
180 ST " [r2]=" REG ",%2;;"
181 "st8 %0=r2;;"
182 : "=m"(misaligned)
183 : "m"(value), "i"(sizeof(DATA_TYPE))
184 : REG, "r2", "memory");
185 # elif POSTINC == ScratchRegPostInc || POSTINC == PreservedRegPostInc
186 return (1);
187 # endif
188
189 block_copy(aligned, data.misaligned, sizeof(DATA_TYPE));
190 #endif
191
192 if (*aligned != value)
193 return (2);
194
195 #if POSTINC == NoPostInc
196 return (0);
197 #elif POSTINC == MinConstPostInc
198 return (((char *)misaligned == data.misaligned - sizeof(DATA_TYPE))
199 ? 0 : 4);
200 #else
201 return (((char *)misaligned == data.misaligned + sizeof(DATA_TYPE))
202 ? 0 : 4);
203 #endif
204 }
205