1139595Smarcel/* 2139595Smarcel * Copyright (c) 2005 Marcel Moolenaar 3139595Smarcel * All rights reserved. 4139595Smarcel * 5139595Smarcel * Redistribution and use in source and binary forms, with or without 6139595Smarcel * modification, are permitted provided that the following conditions 7139595Smarcel * are met: 8139595Smarcel * 9139595Smarcel * 1. Redistributions of source code must retain the above copyright 10139595Smarcel * notice, this list of conditions and the following disclaimer. 11139595Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12139595Smarcel * notice, this list of conditions and the following disclaimer in the 13139595Smarcel * documentation and/or other materials provided with the distribution. 14139595Smarcel * 15139595Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16139595Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17139595Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18139595Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19139595Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20139595Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21139595Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22139595Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23139595Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24139595Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25139595Smarcel * 26139595Smarcel * $FreeBSD$ 27139595Smarcel */ 28139595Smarcel 29140892Smarcel#include <machine/float.h> 30139595Smarcel#include <string.h> 31139595Smarcel 32140892Smarcel/* Memory accesses. */ 33140892Smarcel#define Load 0x01 34140892Smarcel#define Store 0x02 35140892Smarcel 36140892Smarcel/* Data type. */ 37140892Smarcel#define Integer 0x11 38140892Smarcel#define FloatingPoint 0x12 39140892Smarcel 40140892Smarcel/* Data size. */ 41140892Smarcel#define Small 0x21 42140892Smarcel#define Medium 0x22 43140892Smarcel#define Large 0x23 44140892Smarcel 45140892Smarcel/* Post increment. */ 46140892Smarcel#define NoPostInc 0x31 47140892Smarcel#define MinConstPostInc 0x32 48140892Smarcel#define PlusConstPostInc 0x33 49140892Smarcel#define ScratchRegPostInc 0x34 50140892Smarcel#define PreservedRegPostInc 0x35 51140892Smarcel 52140892Smarcel#if ACCESS == 0 || TYPE == 0 || SIZE == 0 || POSTINC == 0 53140892Smarcel#error define ACCESS, TYPE, SIZE and/or POSTINC 54140892Smarcel#endif 55140892Smarcel 56140892Smarcel#if TYPE == Integer 57140892Smarcel# define REG "r8" 58140892Smarcel# if SIZE == Small 59140892Smarcel# define DATA_TYPE short 60140892Smarcel# define DATA_VALUE 0x1234 61140892Smarcel# define LD "ld2" 62140892Smarcel# define ST "st2" 63140892Smarcel# elif SIZE == Medium 64140892Smarcel# define DATA_TYPE int 65140892Smarcel# define DATA_VALUE 0x12345678 66140892Smarcel# define LD "ld4" 67140892Smarcel# define ST "st4" 68140892Smarcel# elif SIZE == Large 69140892Smarcel# define DATA_TYPE long 70140892Smarcel# define DATA_VALUE 0x1234567890ABCDEF 71140892Smarcel# define LD "ld8" 72140892Smarcel# define ST "st8" 73140892Smarcel# endif 74140892Smarcel#elif TYPE == FloatingPoint 75140892Smarcel# define REG "f6" 76140892Smarcel# if SIZE == Small 77140892Smarcel# define DATA_TYPE float 78140892Smarcel# define DATA_VALUE FLT_MIN 79140892Smarcel# define LD "ldfs" 80140892Smarcel# define ST "stfs" 81140892Smarcel# elif SIZE == Medium 82140892Smarcel# define DATA_TYPE double 83140892Smarcel# define DATA_VALUE DBL_MIN 84140892Smarcel# define LD "ldfd" 85140892Smarcel# define ST "stfd" 86140892Smarcel# elif SIZE == Large 87140892Smarcel# define DATA_TYPE long double 88140892Smarcel# define DATA_VALUE LDBL_MIN 89140892Smarcel# define LD "ldfe" 90140892Smarcel# define ST "stfe" 91140892Smarcel# endif 92140892Smarcel#endif 93140892Smarcel 94140919Smarcelstruct { 95139595Smarcel DATA_TYPE aligned; 96139595Smarcel char _; 97139595Smarcel char misaligned[sizeof(DATA_TYPE)]; 98139595Smarcel} data; 99139595Smarcel 100140919SmarcelDATA_TYPE *aligned = &data.aligned; 101140919SmarcelDATA_TYPE *misaligned = (DATA_TYPE *)data.misaligned; 102140919SmarcelDATA_TYPE value = DATA_VALUE; 103140919Smarcel 104140922Smarcelvoid 105140922Smarcelblock_copy(void *dst, void *src, size_t sz) 106140922Smarcel{ 107140922Smarcel 108140922Smarcel memcpy(dst, src, sz); 109140922Smarcel} 110140922Smarcel 111139595Smarcelint 112139595Smarcelmain() 113139595Smarcel{ 114139595Smarcel 115139595Smarcel /* Set PSR.ac. */ 116139595Smarcel asm volatile("sum 8"); 117139595Smarcel 118140892Smarcel#if ACCESS == Load 119140892Smarcel /* 120140892Smarcel * LOAD 121140892Smarcel */ 122140922Smarcel block_copy(misaligned, &value, sizeof(DATA_TYPE)); 123140892Smarcel 124140892Smarcel# if POSTINC == NoPostInc 125140892Smarcel /* Misaligned load. */ 126140892Smarcel *aligned = *misaligned; 127140892Smarcel# elif POSTINC == MinConstPostInc 128140892Smarcel asm volatile( 129140892Smarcel "ld8 r2=%0;;" 130140892Smarcel LD " " REG "=[r2],%2;;" 131140892Smarcel "st8 %0=r2;" ST " %1=" REG ";;" 132140892Smarcel : "=m"(misaligned), "=m"(*aligned) 133140892Smarcel : "i"(-sizeof(DATA_TYPE)) 134140892Smarcel : REG, "r2", "memory"); 135140892Smarcel# elif POSTINC == PlusConstPostInc 136140892Smarcel asm volatile( 137140892Smarcel "ld8 r2=%0;;" 138140892Smarcel LD " " REG "=[r2],%2;;" 139140892Smarcel "st8 %0=r2;" ST " %1=" REG ";;" 140140892Smarcel : "=m"(misaligned), "=m"(*aligned) 141140892Smarcel : "i"(sizeof(DATA_TYPE)) 142140892Smarcel : REG, "r2", "memory"); 143140892Smarcel# elif POSTINC == ScratchRegPostInc 144140892Smarcel asm volatile( 145140892Smarcel "ld8 r2=%0; mov r3=%2;;" 146140892Smarcel LD " " REG "=[r2],r3;;" 147140892Smarcel "st8 %0=r2;" ST " %1=" REG ";;" 148140892Smarcel : "=m"(misaligned), "=m"(*aligned) 149140892Smarcel : "i"(sizeof(DATA_TYPE)) 150140892Smarcel : REG, "r2", "r3", "memory"); 151140892Smarcel# elif POSTINC == PreservedRegPostInc 152140892Smarcel asm volatile( 153140892Smarcel "ld8 r2=%0; mov r4=%2;;" 154140892Smarcel LD " " REG "=[r2],r4;;" 155140892Smarcel "st8 %0=r2;" ST " %1=" REG ";;" 156140892Smarcel : "=m"(misaligned), "=m"(*aligned) 157140892Smarcel : "i"(sizeof(DATA_TYPE)) 158140892Smarcel : REG, "r2", "r4", "memory"); 159140892Smarcel# endif 160140892Smarcel 161140892Smarcel#elif ACCESS == Store 162140892Smarcel /* 163140892Smarcel * STORE 164140892Smarcel */ 165140892Smarcel 166140892Smarcel# if POSTINC == NoPostInc 167139595Smarcel /* Misaligned store. */ 168139595Smarcel *misaligned = value; 169140892Smarcel# elif POSTINC == MinConstPostInc 170140892Smarcel asm volatile( 171140892Smarcel "ld8 r2=%0;" LD " " REG "=%1;;" 172140892Smarcel ST " [r2]=" REG ",%2;;" 173140892Smarcel "st8 %0=r2;;" 174140892Smarcel : "=m"(misaligned) 175140892Smarcel : "m"(value), "i"(-sizeof(DATA_TYPE)) 176140892Smarcel : REG, "r2", "memory"); 177140892Smarcel# elif POSTINC == PlusConstPostInc 178140892Smarcel asm volatile( 179140892Smarcel "ld8 r2=%0;" LD " " REG "=%1;;" 180140892Smarcel ST " [r2]=" REG ",%2;;" 181140892Smarcel "st8 %0=r2;;" 182140892Smarcel : "=m"(misaligned) 183140892Smarcel : "m"(value), "i"(sizeof(DATA_TYPE)) 184140892Smarcel : REG, "r2", "memory"); 185140892Smarcel# elif POSTINC == ScratchRegPostInc || POSTINC == PreservedRegPostInc 186140892Smarcel return (1); 187140892Smarcel# endif 188140892Smarcel 189140922Smarcel block_copy(aligned, data.misaligned, sizeof(DATA_TYPE)); 190140892Smarcel#endif 191140892Smarcel 192140892Smarcel if (*aligned != value) 193140892Smarcel return (2); 194140892Smarcel 195140892Smarcel#if POSTINC == NoPostInc 196140892Smarcel return (0); 197140892Smarcel#elif POSTINC == MinConstPostInc 198140892Smarcel return (((char *)misaligned == data.misaligned - sizeof(DATA_TYPE)) 199140892Smarcel ? 0 : 4); 200139595Smarcel#else 201140892Smarcel return (((char *)misaligned == data.misaligned + sizeof(DATA_TYPE)) 202140892Smarcel ? 0 : 4); 203139595Smarcel#endif 204139595Smarcel} 205