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$ 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 94struct { 95 DATA_TYPE aligned; 96 char _; 97 char misaligned[sizeof(DATA_TYPE)]; 98} data; 99 100DATA_TYPE *aligned = &data.aligned; 101DATA_TYPE *misaligned = (DATA_TYPE *)data.misaligned; 102DATA_TYPE value = DATA_VALUE; 103 104void 105block_copy(void *dst, void *src, size_t sz) 106{ 107 108 memcpy(dst, src, sz); 109} 110 111int 112main() 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