1 /* memory access abstraction layer for forth kernel 2 * 3 * Copyright (C) 2005 Stefan Reinauer 4 * 5 * See the file "COPYING" for further information about 6 * the copyright and warranty status of this work. 7 */ 8 9 #ifndef __CROSS_H 10 #define __CROSS_H 1 11 12 /* The forthstrap compiler has to abstract the underlying dictionary 13 * type: big/little endian, 32/64bit. All other binaries shall use 14 * unchanged memory access for performance. 15 */ 16 17 /* byte swapping */ 18 19 #ifndef SWAP_ENDIANNESS 20 21 /* trivial case - we don't have to change anything */ 22 #define read_ucell(addr) (*(ucell *)(addr)) 23 #define read_cell(addr) (*(cell *)(addr)) 24 #define read_long(addr) (*(u32 *)(addr)) 25 #define read_word(addr) (*(u16 *)(addr)) 26 #define read_byte(addr) (*(u8 *)(addr)) 27 28 #define write_ucell(addr, value) {*(ucell *)(addr)=(value);} 29 #define write_cell(addr, value) {*(cell *)(addr)=(value);} 30 #define write_long(addr, value) {*(u32 *)(addr)=(value);} 31 #define write_word(addr, value) {*(u16 *)(addr)=(value);} 32 #define write_byte(addr, value) {*(u8 *)(addr)=(value);} 33 34 #define target_ucell(x) (x) 35 #define target_cell(x) (x) 36 #define target_long(x) (x) 37 #define target_ulong(x) (x) 38 39 #else /* SWAP_ENDIANNESS */ 40 41 #define target_word(value) ( (((value)>>8)&0xff) | (((value)&0xff)<<8) ) 42 #define target_long(value) ( (((value)&0xff000000)>>24)|(((value)&0x00ff0000)>>8)|(((value)&0xff00)<<8)|(((value)&0xff)<<24) ) 43 #define target_ulong(value) (target_long(value)) 44 45 #if BITS==32 46 #define target_ucell(value) ((ucell)target_long(value)) 47 #define target_cell(value) ((cell)target_long(value)) 48 #elif BITS==64 49 #define target_ucell(value) \ 50 ((((ucell)target_long((value) & 0xffffffff)) << 32) | \ 51 ((ucell)target_long((value) >> 32))) 52 #define target_cell(value) \ 53 ((((cell)target_long((value) & 0xffffffff)) << 32) | \ 54 ((cell)target_long((value) >> 32))) 55 #else 56 #error "Endianness not supported. Please report." 57 #endif 58 59 #define read_ucell(addr) target_ucell(*(ucell *)(addr)) 60 #define read_cell(addr) target_cell(*(cell *)(addr)) 61 #define read_long(addr) target_long(*(u32 *)(addr)) 62 #define read_word(addr) target_word(*(u16 *)(addr)) 63 #define read_byte(addr) (*(u8 *)(addr)) 64 65 #define write_ucell(addr, value) {*(ucell *)(addr)=target_ucell(value);} 66 #define write_cell(addr, value) {*(cell *)(addr)=target_cell(value);} 67 #define write_long(addr, value) {*(u32 *)(addr)=target_long(value);} 68 #define write_word(addr, value) {*(u16 *)(addr)=target_word(value);} 69 #define write_byte(addr, value) {*(u8 *)(addr)=(value);} 70 #endif 71 72 #ifdef CONFIG_LITTLE_ENDIAN 73 #define unaligned_read_word(addr) \ 74 (read_byte(addr)|(read_byte((u8 *)addr+1)<<8)) 75 76 #define unaligned_read_long(addr) \ 77 (unaligned_read_word(addr)|(unaligned_read_word((u8 *)addr+2)<<16)) 78 79 #define unaligned_write_word(addr, value) \ 80 write_byte(addr, (value & 0xff)); write_byte((u8 *)(addr+1), (value>>8)) 81 82 #define unaligned_write_long(addr, value) \ 83 unaligned_write_word(addr, (value & 0xffff)); \ 84 unaligned_write_word((addr + 2), (value >> 16)) 85 86 #endif 87 88 #ifdef CONFIG_BIG_ENDIAN 89 #define unaligned_read_word(addr) \ 90 ((read_byte(addr)<<8)|read_byte((u8 *)addr+1)) 91 92 #define unaligned_read_long(addr) \ 93 ((unaligned_read_word(addr)<<16)|unaligned_read_word((u8 *)addr+2)) 94 95 #define unaligned_write_word(addr, value) \ 96 write_byte(addr, (value >> 8)); write_byte((u8 *)(addr+1), (value & 0xff)) 97 98 #define unaligned_write_long(addr, value) \ 99 unaligned_write_word(addr, (value >> 16)); \ 100 unaligned_write_word((addr + 2), (value & 0xffff)) 101 #endif 102 103 /* bit width handling */ 104 105 #if BITS==32 106 #define FMT_CELL_x PRIx32 107 #define FMT_CELL_d PRId32 108 #else 109 #define FMT_CELL_x PRIx64 110 #define FMT_CELL_d PRId64 111 #endif 112 113 #ifdef NATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH 114 extern unsigned long base_address; 115 #define pointer2cell(x) ((ucell)(((unsigned long)(x))-base_address)) 116 #define cell2pointer(x) ((u8 *)(((unsigned long)(x))+base_address)) 117 #endif 118 119 #ifdef NATIVE_BITWIDTH_LARGER_THAN_HOST_BITWIDTH 120 #define pointer2cell(x) ((ucell)(unsigned long)(x)) 121 #define cell2pointer(x) ((u8 *)((unsigned long)(x)&0xFFFFFFFFUL)) 122 #endif 123 124 #endif 125