1178676Ssam/*
2210111Sbschmidt * Copyright (c) 2005 Marcel Moolenaar
3178676Ssam * All rights reserved.
4178676Ssam *
5198429Srpaulo * Redistribution and use in source and binary forms, with or without
6178676Ssam * modification, are permitted provided that the following conditions
7178676Ssam * are met:
8178676Ssam *
9178676Ssam * 1. Redistributions of source code must retain the above copyright
10178676Ssam *    notice, this list of conditions and the following disclaimer.
11178676Ssam * 2. Redistributions in binary form must reproduce the above copyright
12178676Ssam *    notice, this list of conditions and the following disclaimer in the
13178676Ssam *    documentation and/or other materials provided with the distribution.
14178676Ssam *
15178676Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16178676Ssam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17178676Ssam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18178676Ssam * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19178676Ssam * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20178676Ssam * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21253898Sadrian * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22253898Sadrian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23253898Sadrian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24178676Ssam * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25198429Srpaulo *
26198429Srpaulo * $FreeBSD: releng/10.2/tools/regression/ia64/unaligned/test.c 140922 2005-01-28 02:58:32Z marcel $
27198429Srpaulo */
28198429Srpaulo
29178676Ssam#include <machine/float.h>
30198429Srpaulo#include <string.h>
31198429Srpaulo
32178676Ssam/* Memory accesses. */
33221651Sbschmidt#define	Load			0x01
34221651Sbschmidt#define	Store			0x02
35221651Sbschmidt
36198429Srpaulo/* Data type. */
37198429Srpaulo#define	Integer			0x11
38178676Ssam#define	FloatingPoint		0x12
39198429Srpaulo
40198429Srpaulo/* Data size. */
41201209Srpaulo#define	Small			0x21
42201209Srpaulo#define	Medium			0x22
43201209Srpaulo#define	Large			0x23
44253898Sadrian
45253898Sadrian/* Post increment. */
46253898Sadrian#define	NoPostInc		0x31
47253898Sadrian#define	MinConstPostInc		0x32
48198429Srpaulo#define	PlusConstPostInc	0x33
49178676Ssam#define	ScratchRegPostInc	0x34
50178676Ssam#define	PreservedRegPostInc	0x35
51198429Srpaulo
52178676Ssam#if ACCESS == 0 || TYPE == 0 || SIZE == 0 || POSTINC == 0
53178676Ssam#error define ACCESS, TYPE, SIZE and/or POSTINC
54198429Srpaulo#endif
55198429Srpaulo
56198429Srpaulo#if TYPE == Integer
57198429Srpaulo#  define	REG		"r8"
58198429Srpaulo#  if SIZE == Small
59198429Srpaulo#    define	DATA_TYPE	short
60198429Srpaulo#    define	DATA_VALUE	0x1234
61198429Srpaulo#    define	LD		"ld2"
62198429Srpaulo#    define	ST		"st2"
63178676Ssam#  elif SIZE == Medium
64178676Ssam#    define	DATA_TYPE	int
65178676Ssam#    define	DATA_VALUE	0x12345678
66198429Srpaulo#    define	LD		"ld4"
67198429Srpaulo#    define	ST		"st4"
68201209Srpaulo#  elif SIZE == Large
69198429Srpaulo#    define	DATA_TYPE	long
70201209Srpaulo#    define	DATA_VALUE	0x1234567890ABCDEF
71198429Srpaulo#    define	LD		"ld8"
72253866Sadrian#    define	ST		"st8"
73178676Ssam#  endif
74198429Srpaulo#elif TYPE == FloatingPoint
75198429Srpaulo#  define	REG		"f6"
76198429Srpaulo#  if SIZE == Small
77198429Srpaulo#    define	DATA_TYPE	float
78198429Srpaulo#    define	DATA_VALUE	FLT_MIN
79198429Srpaulo#    define	LD		"ldfs"
80253866Sadrian#    define	ST		"stfs"
81201209Srpaulo#  elif SIZE == Medium
82253866Sadrian#    define	DATA_TYPE	double
83253866Sadrian#    define	DATA_VALUE	DBL_MIN
84198429Srpaulo#    define	LD		"ldfd"
85253866Sadrian#    define	ST		"stfd"
86198429Srpaulo#  elif SIZE == Large
87201209Srpaulo#    define	DATA_TYPE	long double
88220729Sbschmidt#    define	DATA_VALUE	LDBL_MIN
89198429Srpaulo#    define	LD		"ldfe"
90198429Srpaulo#    define	ST		"stfe"
91201209Srpaulo#  endif
92198429Srpaulo#endif
93201209Srpaulo
94253866Sadrianstruct {
95198429Srpaulo	DATA_TYPE aligned;
96178676Ssam	char _;
97178676Ssam	char misaligned[sizeof(DATA_TYPE)];
98198429Srpaulo} data;
99253898Sadrian
100220726SbschmidtDATA_TYPE *aligned = &data.aligned;
101220726SbschmidtDATA_TYPE *misaligned = (DATA_TYPE *)data.misaligned;
102220726SbschmidtDATA_TYPE value = DATA_VALUE;
103220726Sbschmidt
104198429Srpaulovoid
105178676Ssamblock_copy(void *dst, void *src, size_t sz)
106198429Srpaulo{
107198429Srpaulo
108198429Srpaulo	memcpy(dst, src, sz);
109198429Srpaulo}
110198429Srpaulo
111198429Srpauloint
112198429Srpaulomain()
113198429Srpaulo{
114198429Srpaulo
115198429Srpaulo	/* Set PSR.ac. */
116198429Srpaulo	asm volatile("sum 8");
117198429Srpaulo
118198429Srpaulo#if ACCESS == Load
119198429Srpaulo	/*
120198429Srpaulo	 * LOAD
121198429Srpaulo	 */
122198429Srpaulo	block_copy(misaligned, &value, sizeof(DATA_TYPE));
123178676Ssam
124198429Srpaulo#  if POSTINC == NoPostInc
125198429Srpaulo	/* Misaligned load. */
126198429Srpaulo	*aligned = *misaligned;
127198429Srpaulo#  elif POSTINC == MinConstPostInc
128198429Srpaulo	asm volatile(
129198429Srpaulo		"ld8 r2=%0;;"
130198429Srpaulo		LD " " REG "=[r2],%2;;"
131198429Srpaulo		"st8 %0=r2;" ST " %1=" REG ";;"
132198429Srpaulo	    : "=m"(misaligned), "=m"(*aligned)
133198429Srpaulo	    : "i"(-sizeof(DATA_TYPE))
134198429Srpaulo	    : REG, "r2", "memory");
135198429Srpaulo#  elif POSTINC == PlusConstPostInc
136198429Srpaulo	asm volatile(
137198429Srpaulo		"ld8 r2=%0;;"
138198429Srpaulo		LD " " REG "=[r2],%2;;"
139198429Srpaulo		"st8 %0=r2;" ST " %1=" REG ";;"
140198429Srpaulo	    : "=m"(misaligned), "=m"(*aligned)
141198429Srpaulo	    : "i"(sizeof(DATA_TYPE))
142178676Ssam	    : REG, "r2", "memory");
143178676Ssam#  elif POSTINC == ScratchRegPostInc
144198429Srpaulo	asm volatile(
145198429Srpaulo		"ld8 r2=%0; mov r3=%2;;"
146198429Srpaulo		LD " " REG "=[r2],r3;;"
147198429Srpaulo		"st8 %0=r2;" ST " %1=" REG ";;"
148198429Srpaulo	    : "=m"(misaligned), "=m"(*aligned)
149198429Srpaulo	    : "i"(sizeof(DATA_TYPE))
150198429Srpaulo	    : REG, "r2", "r3", "memory");
151198429Srpaulo#  elif POSTINC == PreservedRegPostInc
152198429Srpaulo	asm volatile(
153198429Srpaulo		"ld8 r2=%0; mov r4=%2;;"
154198429Srpaulo		LD " " REG "=[r2],r4;;"
155198429Srpaulo		"st8 %0=r2;" ST " %1=" REG ";;"
156178676Ssam	    : "=m"(misaligned), "=m"(*aligned)
157178676Ssam	    : "i"(sizeof(DATA_TYPE))
158201209Srpaulo	    : REG, "r2", "r4", "memory");
159201209Srpaulo#  endif
160198429Srpaulo
161198429Srpaulo#elif ACCESS == Store
162201209Srpaulo	/*
163201209Srpaulo	 * STORE
164198429Srpaulo	 */
165198429Srpaulo
166198429Srpaulo#  if POSTINC == NoPostInc
167198429Srpaulo	/* Misaligned store. */
168198429Srpaulo	*misaligned = value;
169198429Srpaulo#  elif POSTINC == MinConstPostInc
170198429Srpaulo	asm volatile(
171198429Srpaulo		"ld8 r2=%0;" LD " " REG "=%1;;"
172198429Srpaulo		ST " [r2]=" REG ",%2;;"
173198429Srpaulo		"st8 %0=r2;;"
174178676Ssam	    : "=m"(misaligned)
175198429Srpaulo	    : "m"(value), "i"(-sizeof(DATA_TYPE))
176198429Srpaulo	    : REG, "r2", "memory");
177198429Srpaulo#  elif POSTINC == PlusConstPostInc
178198429Srpaulo	asm volatile(
179198429Srpaulo		"ld8 r2=%0;" LD " " REG "=%1;;"
180198429Srpaulo		ST " [r2]=" REG ",%2;;"
181198429Srpaulo		"st8 %0=r2;;"
182198429Srpaulo	    : "=m"(misaligned)
183198429Srpaulo	    : "m"(value), "i"(sizeof(DATA_TYPE))
184178676Ssam	    : REG, "r2", "memory");
185201209Srpaulo#  elif POSTINC == ScratchRegPostInc || POSTINC == PreservedRegPostInc
186201209Srpaulo	return (1);
187201209Srpaulo#  endif
188201209Srpaulo
189198429Srpaulo	block_copy(aligned, data.misaligned, sizeof(DATA_TYPE));
190198429Srpaulo#endif
191178676Ssam
192198429Srpaulo	if (*aligned != value)
193198429Srpaulo		return (2);
194198429Srpaulo
195178676Ssam#if POSTINC == NoPostInc
196198429Srpaulo	return (0);
197198429Srpaulo#elif POSTINC == MinConstPostInc
198198429Srpaulo	return (((char *)misaligned == data.misaligned - sizeof(DATA_TYPE))
199198429Srpaulo	    ? 0 : 4);
200198429Srpaulo#else
201261455Seadler	return (((char *)misaligned == data.misaligned + sizeof(DATA_TYPE))
202178676Ssam	    ? 0 : 4);
203198429Srpaulo#endif
204198429Srpaulo}
205198429Srpaulo