rockbox/firmware/target/sh/system-target.h
Thomas Martitz 991ae1e395 Create fimrware/asm directory for assembly optimized stuff.
This dir is suitable for stuff that doesn't fit the target tree, e.g. because
it also builds on hosted or otherwise. It also has a generic subfolder for
fallback C implementations so that not all archs need to provide asm files.

SOURCES should only contain "foo.c" where foo.c includes the specific
<arch>/foo.c files from the subdirs using the preprocessor. This way automatic
selection of asm versions or generic C verion is possible.

For the start, the thread support files are moved, since ASM threads can
be used on hosted platforms as well. Since core_sleep() remains platform
specific it's moved to the corresponding system.h headers.

Change-Id: Iebff272f3407a6eaafeb7656ceb0ae9eca3f7cb9
2012-01-22 18:46:44 +01:00

154 lines
4.6 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2007 by Jens Arnold
* Based on the work of Alan Korr and others
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef SYSTEM_TARGET_H
#define SYSTEM_TARGET_H
#define or_b(mask, address) \
asm \
("or.b %0,@(r0,gbr)" \
: \
: /* %0 */ I_CONSTRAINT((char)(mask)), \
/* %1 */ "z"(address-GBR))
#define and_b(mask, address) \
asm \
("and.b %0,@(r0,gbr)" \
: \
: /* %0 */ I_CONSTRAINT((char)(mask)), \
/* %1 */ "z"(address-GBR))
#define xor_b(mask, address) \
asm \
("xor.b %0,@(r0,gbr)" \
: \
: /* %0 */ I_CONSTRAINT((char)(mask)), \
/* %1 */ "z"(address-GBR))
/****************************************************************************
* Interrupt level setting
* The level is left shifted 4 bits
****************************************************************************/
#define HIGHEST_IRQ_LEVEL (15<<4)
static inline int set_irq_level(int level)
{
int i;
/* Read the old level and set the new one */
/* Not volatile - will be optimized away if the return value isn't used */
asm ("stc sr, %0" : "=r" (i));
asm volatile ("ldc %0, sr" : : "r" (level));
return i;
}
static inline void enable_irq(void)
{
int i;
asm volatile ("mov %1, %0 \n" /* Save a constant load from RAM */
"ldc %0, sr \n" : "=&r"(i) : "i"(0));
}
#define disable_irq() \
((void)set_irq_level(HIGHEST_IRQ_LEVEL))
#define disable_irq_save() \
set_irq_level(HIGHEST_IRQ_LEVEL)
#define restore_irq(i) \
((void)set_irq_level(i))
static inline uint16_t swap16_hw(uint16_t value)
/*
result[15..8] = value[ 7..0];
result[ 7..0] = value[15..8];
*/
{
uint16_t result;
asm ("swap.b\t%1,%0" : "=r"(result) : "r"(value));
return result;
}
static inline uint32_t swaw32_hw(uint32_t value)
/*
result[31..16] = value[15.. 0];
result[15.. 0] = value[31..16];
*/
{
uint32_t result;
asm ("swap.w\t%1,%0" : "=r"(result) : "r"(value));
return result;
}
static inline uint32_t swap32_hw(uint32_t value)
/*
result[31..24] = value[ 7.. 0];
result[23..16] = value[15.. 8];
result[15.. 8] = value[23..16];
result[ 7.. 0] = value[31..24];
*/
{
asm ("swap.b\t%0,%0\n"
"swap.w\t%0,%0\n"
"swap.b\t%0,%0\n" : "+r"(value));
return value;
}
static inline uint32_t swap_odd_even32_hw(uint32_t value)
{
/*
result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
*/
asm ("swap.b\t%0,%0\n"
"swap.w\t%0,%0\n"
"swap.b\t%0,%0\n"
"swap.w\t%0,%0\n" : "+r"(value));
return value;
}
extern const unsigned bit_n_table[32];
#define BIT_N(n) ( \
__builtin_constant_p(n) \
? (1U << (n)) \
: bit_n_table[n] \
)
static inline void commit_dcache(void) {}
static inline void commit_discard_dcache(void) {}
static inline void commit_discard_idcache(void) {}
/*---------------------------------------------------------------------------
* Put core in a power-saving state.
*---------------------------------------------------------------------------
*/
static inline void core_sleep(void)
{
asm volatile (
"and.b #0x7f, @(r0, gbr) \n" /* Clear SBY (bit 7) in SBYCR */
"mov #0, r1 \n" /* Enable interrupts */
"ldc r1, sr \n" /* Following instruction cannot be interrupted */
"sleep \n" /* Execute standby */
: : "z"(&SBYCR-GBR) : "r1");
}
#endif /* SYSTEM_TARGET_H */