84 lines
3.1 KiB
C
84 lines
3.1 KiB
C
/* or1k-asm.h -- OR1K assembly helper macros
|
|
|
|
Copyright (c) 2014 OpenRISC Project Maintainers
|
|
Copyright (C) 2012-2014 Peter Gavin <pgavin@gmail.com>
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following condition
|
|
is met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
#ifndef OR1K_ASM_H
|
|
#define OR1K_ASM_H
|
|
|
|
/* The purpose of the OR1K_INST macro is simply to protect the commas
|
|
embedded within an instruction from the C preprocessor. An entire
|
|
instruction can be safely embedded within its arguments, including
|
|
an arbitrary number of commas, and it will be reproduced
|
|
exactly. */
|
|
#define OR1K_INST(...) __VA_ARGS__
|
|
|
|
/* OR1K_DELAYED takes two arguments which must be instructions. They
|
|
should be wrapped in OR1K_INST if the instructions require commas.
|
|
The second argument should be a jump or branch instruction. If we
|
|
are assembling the code in delay-slot mode (e.g., for the standard
|
|
OR1K) the first instruction will be emitted in the delay slot of
|
|
the second instruction. In no-delay-slot mode they will be emitted
|
|
in order. If we are using compat-delay mode, they will be emitted
|
|
in order, but an l.nop instruction will be emitted immediately
|
|
after. */
|
|
|
|
/* OR1K_DELAYED_NOP takes a single argument, which should be a
|
|
branch/jump instruction. In delay-slot or compat-delay modes, the
|
|
instruction will be emitted with an l.nop in its delay slot. In
|
|
no-delay mode, the instruction will be emitted by itself. */
|
|
|
|
#if defined(__OR1K_NODELAY__)
|
|
|
|
#define OR1K_DELAYED(a, b) a; b
|
|
#define OR1K_DELAYED_NOP(a) a
|
|
|
|
/* Go ahead and emit the .nodelay directive when in no-delay mode, so
|
|
that the flags are appropriately set in the binary. */
|
|
.nodelay
|
|
|
|
#elif defined(__OR1K_DELAY__)
|
|
|
|
#define OR1K_DELAYED(a, b) b; a
|
|
#define OR1K_DELAYED_NOP(a) a; l.nop
|
|
|
|
#elif defined(__OR1K_DELAY_COMPAT__)
|
|
|
|
#define OR1K_DELAYED(a, b) a; b; l.nop
|
|
#define OR1K_DELAYED_NOP(a) a; l.nop
|
|
|
|
#else
|
|
|
|
#error One of __OR1K_NODELAY__, __OR1K_DELAY__, or __OR1K_DELAY_COMPAT__ must be defined
|
|
|
|
#endif
|
|
|
|
#define LOAD_SYMBOL_2_GPR(gpr,symbol) \
|
|
.global symbol ; \
|
|
l.movhi gpr, hi(symbol) ; \
|
|
l.ori gpr, gpr, lo(symbol)
|
|
#endif
|