Files
openbios/kernel/cross.h
Andreas Färber 595b99dc36 Consolidate cell format defines
When cross-compiling ppc64 from ppc (native larger than host),
%llx cell format leads to warnings.

The cell format depends solely on the cell type definition,
not on pointer sizes. Under the present assumption that native
smaller than host bitwidth occurs when cross-compiling a 32-bit
target from 64-bit host, we can reuse the definitions from the
equality path for all bitwidths.

Signed-off-by: Andreas Färber <andreas.faerber@web.de>


git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@940 f158a5a8-5612-0410-a976-696ce0be7e32
2010-10-31 16:54:58 +00:00

125 lines
4.1 KiB
C

/* memory access abstraction layer for forth kernel
*
* Copyright (C) 2005 Stefan Reinauer
*
* See the file "COPYING" for further information about
* the copyright and warranty status of this work.
*/
#ifndef __CROSS_H
#define __CROSS_H 1
/* The forthstrap compiler has to abstract the underlying dictionary
* type: big/little endian, 32/64bit. All other binaries shall use
* unchanged memory access for performance.
*/
/* byte swapping */
#ifndef SWAP_ENDIANNESS
/* trivial case - we don't have to change anything */
#define read_ucell(addr) (*(ucell *)(addr))
#define read_cell(addr) (*(cell *)(addr))
#define read_long(addr) (*(u32 *)(addr))
#define read_word(addr) (*(u16 *)(addr))
#define read_byte(addr) (*(u8 *)(addr))
#define write_ucell(addr, value) {*(ucell *)(addr)=(value);}
#define write_cell(addr, value) {*(cell *)(addr)=(value);}
#define write_long(addr, value) {*(u32 *)(addr)=(value);}
#define write_word(addr, value) {*(u16 *)(addr)=(value);}
#define write_byte(addr, value) {*(u8 *)(addr)=(value);}
#define target_ucell(x) (x)
#define target_cell(x) (x)
#define target_long(x) (x)
#define target_ulong(x) (x)
#else /* SWAP_ENDIANNESS */
#define target_word(value) ( (((value)>>8)&0xff) | (((value)&0xff)<<8) )
#define target_long(value) ( (((value)&0xff000000)>>24)|(((value)&0x00ff0000)>>8)|(((value)&0xff00)<<8)|(((value)&0xff)<<24) )
#define target_ulong(value) (target_long(value))
#if BITS==32
#define target_ucell(value) ((ucell)target_long(value))
#define target_cell(value) ((cell)target_long(value))
#elif BITS==64
#define target_ucell(value) \
((((ucell)target_long((value) & 0xffffffff)) << 32) | \
((ucell)target_long((value) >> 32)))
#define target_cell(value) \
((((cell)target_long((value) & 0xffffffff)) << 32) | \
((cell)target_long((value) >> 32)))
#else
#error "Endianness not supported. Please report."
#endif
#define read_ucell(addr) target_ucell(*(ucell *)(addr))
#define read_cell(addr) target_cell(*(cell *)(addr))
#define read_long(addr) target_long(*(u32 *)(addr))
#define read_word(addr) target_word(*(u16 *)(addr))
#define read_byte(addr) (*(u8 *)(addr))
#define write_ucell(addr, value) {*(ucell *)(addr)=target_ucell(value);}
#define write_cell(addr, value) {*(cell *)(addr)=target_cell(value);}
#define write_long(addr, value) {*(u32 *)(addr)=target_long(value);}
#define write_word(addr, value) {*(u16 *)(addr)=target_word(value);}
#define write_byte(addr, value) {*(u8 *)(addr)=(value);}
#endif
#ifdef CONFIG_LITTLE_ENDIAN
#define unaligned_read_word(addr) \
(read_byte(addr)|(read_byte((u8 *)addr+1)<<8))
#define unaligned_read_long(addr) \
(unaligned_read_word(addr)|(unaligned_read_word((u8 *)addr+2)<<16))
#define unaligned_write_word(addr, value) \
write_byte(addr, (value & 0xff)); write_byte((u8 *)(addr+1), (value>>8))
#define unaligned_write_long(addr, value) \
unaligned_write_word(addr, (value & 0xffff)); \
unaligned_write_word((addr + 2), (value >> 16))
#endif
#ifdef CONFIG_BIG_ENDIAN
#define unaligned_read_word(addr) \
((read_byte(addr)<<8)|read_byte((u8 *)addr+1))
#define unaligned_read_long(addr) \
((unaligned_read_word(addr)<<16)|unaligned_read_word((u8 *)addr+2))
#define unaligned_write_word(addr, value) \
write_byte(addr, (value >> 8)); write_byte((u8 *)(addr+1), (value & 0xff))
#define unaligned_write_long(addr, value) \
unaligned_write_word(addr, (value >> 16)); \
unaligned_write_word((addr + 2), (value & 0xffff))
#endif
/* bit width handling */
#if BITS==32
#define FMT_CELL_x "x"
#define FMT_CELL_d "d"
#else
#define FMT_CELL_x "llx"
#define FMT_CELL_d "lld"
#endif
#ifdef NATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH
extern unsigned long base_address;
#define pointer2cell(x) ((ucell)(((unsigned long)(x))-base_address))
#define cell2pointer(x) ((u8 *)(((unsigned long)(x))+base_address))
#endif
#ifdef NATIVE_BITWIDTH_LARGER_THAN_HOST_BITWIDTH
#define pointer2cell(x) ((ucell)(unsigned long)(x))
#define cell2pointer(x) ((u8 *)((unsigned long)(x)&0xFFFFFFFFUL))
#endif
#endif