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