binutils-gdb/sim/testsuite/or1k/or1k-asm-test.h
Mike Frysinger 1368b914e9 sim: testsuite: flatten tree
Now that all port tests live under testsuite/sim/*/, and none live
in testsuite/ directly, flatten the structure by moving all of the
dirs under testsuite/sim/ to testsuite/ directly.

We need to stop passing --tool to dejagnu so that it searches all
dirs and not just ones that start with "sim".  Since we have no
other dirs in this tree, and no plans to add any, should be fine.
2021-01-15 19:18:34 -05:00

227 lines
6.1 KiB
C

/* Testsuite architecture macros for OpenRISC.
Copyright (C) 2017-2021 Free Software Foundation, Inc.
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef OR1K_ASM_TEST_H
#define OR1K_ASM_TEST_H
#include "spr-defs.h"
/* Register definitions */
/* The "jump and link" instructions store the return address in R9. */
#define LINK_REGISTER_R9 r9
/* These register definitions match the ABI. */
#define ZERO_R0 r0
#define STACK_POINTER_R1 r1
#define FRAME_POINTER_R2 r2
#define RETURN_VALUE_R11 r11
/* Load/move/clear helpers */
.macro LOAD_IMMEDIATE reg, val
l.movhi \reg, hi ( \val )
l.ori \reg, \reg, lo ( \val )
.endm
.macro MOVE_REG dest_reg, src_reg
.ifnes "\dest_reg","\src_reg"
l.ori \dest_reg, \src_reg, 0
.endif
.endm
.macro CLEAR_REG reg
l.movhi \reg, 0
.endm
.macro MOVE_FROM_SPR reg, spr_reg
l.mfspr \reg, ZERO_R0, \spr_reg
.endm
.macro MOVE_TO_SPR spr_reg, reg
l.mtspr ZERO_R0, \reg, \spr_reg
.endm
.macro SET_SPR_SR_FLAGS flag_mask, scratch_reg_1, scratch_reg_2
/* We cannot use PUSH and POP here because some flags like Carry
would get overwritten. */
/* We could optimise this routine, as instruction l.mtspr already
does a logical OR. */
MOVE_FROM_SPR \scratch_reg_2, SPR_SR
LOAD_IMMEDIATE \scratch_reg_1, \flag_mask
l.or \scratch_reg_2, \scratch_reg_2, \scratch_reg_1
MOVE_TO_SPR SPR_SR, \scratch_reg_2
.endm
.macro CLEAR_SPR_SR_FLAGS flag_mask, scratch_reg_1, scratch_reg_2
/* We cannot use PUSH and POP here because some flags like Carry
would get overwritten. */
MOVE_FROM_SPR \scratch_reg_2, SPR_SR
LOAD_IMMEDIATE \scratch_reg_1, ~\flag_mask
l.and \scratch_reg_2, \scratch_reg_2, \scratch_reg_1
MOVE_TO_SPR SPR_SR, \scratch_reg_2
.endm
/* Stack helpers */
/* This value is defined in the OpenRISC 1000 specification. */
#define EXCEPTION_STACK_SKIP_SIZE 128
/* WARNING: Functions without prolog cannot use these PUSH or POP
macros.
PERFORMANCE WARNING: These PUSH/POP macros are convenient, but
can lead to slow code. If you need to PUSH or POP several
registers, it's faster to use non-zero offsets when
loading/storing and then increment/decrement the stack pointer
just once. */
.macro PUSH reg
l.addi STACK_POINTER_R1, STACK_POINTER_R1, -4
l.sw 0(STACK_POINTER_R1), \reg
.endm
/* WARNING: see the warnings for PUSH. */
.macro POP reg
l.lwz \reg, 0(STACK_POINTER_R1)
l.addi STACK_POINTER_R1, STACK_POINTER_R1, 4
.endm
/* l.nop definitions for simulation control and console output. */
/* Register definitions for the simulation l.nop codes. */
#define NOP_REPORT_R3 r3
#define NOP_EXIT_R3 r3
/* SEC = Simulation Exit Code */
#define SEC_SUCCESS 0
#define SEC_RETURNED_FROM_MAIN 1
#define SEC_GENERIC_ERROR 2
/* When running under the simulator, this l.nop code terminates the
simulation. */
.macro EXIT_SIMULATION_WITH_IMMEDIATE_EXIT_CODE immediate_value
LOAD_IMMEDIATE NOP_EXIT_R3, \immediate_value
l.nop 1
.endm
.macro EXIT_SIMULATION_WITH_REG_EXIT_CODE reg
MOVE_REG NOP_EXIT_R3, \reg
l.nop 1
.endm
/* When running under the simulator, this l.nop code prints the
value of R3 to the console. */
.macro REPORT_TO_CONSOLE
l.nop 2
.endm
/* NOTE: The stack must be set up, as this macro uses PUSH and POP. */
.macro REPORT_REG_TO_CONSOLE reg
.ifeqs "\reg","r3"
/* Nothing more to do here, R3 is the register that gets printed. */
REPORT_TO_CONSOLE
.else
PUSH NOP_REPORT_R3
MOVE_REG NOP_REPORT_R3, \reg
REPORT_TO_CONSOLE
POP NOP_REPORT_R3
.endif
.endm
/* NOTE: The stack must be set up, as this macro uses PUSH and POP. */
.macro REPORT_IMMEDIATE_TO_CONSOLE val
PUSH NOP_REPORT_R3
LOAD_IMMEDIATE NOP_REPORT_R3, \val
REPORT_TO_CONSOLE
POP NOP_REPORT_R3
.endm
.macro PRINT_NEWLINE_TO_CONSOLE
PUSH r3
LOAD_IMMEDIATE r3, 0x0A
l.nop 4
POP r3
.endm
/* If SR[F] is set, writes 0x00000001 to the console, otherwise it
writes 0x00000000. */
.macro REPORT_SRF_TO_CONSOLE
OR1K_DELAYED_NOP (l.bnf \@1$)
REPORT_IMMEDIATE_TO_CONSOLE 0x00000001
OR1K_DELAYED_NOP (l.j \@2$)
\@1$:
REPORT_IMMEDIATE_TO_CONSOLE 0x00000000
\@2$:
.endm
/* If the given register is 0, writes 0x00000000 to the console,
otherwise it writes 0x00000001. */
.macro REPORT_BOOL_TO_CONSOLE reg
l.sfne \reg, ZERO_R0
REPORT_SRF_TO_CONSOLE
.endm
/* Writes to the console the value of the given register bit. */
.macro REPORT_BIT_TO_CONSOLE reg, single_bit_mask
PUSH r2
PUSH r3
PUSH r4
MOVE_REG r2, \reg
LOAD_IMMEDIATE r4, \single_bit_mask
l.and r3, r2, r4
REPORT_BOOL_TO_CONSOLE r3
POP r4
POP r3
POP r2
.endm
/* Jump helpers */
.macro CALL overwritten_reg, subroutine_name
LOAD_IMMEDIATE \overwritten_reg, \subroutine_name
OR1K_DELAYED_NOP (l.jalr \overwritten_reg)
.endm
.macro RETURN_TO_LINK_REGISTER_R9
OR1K_DELAYED_NOP (l.jr LINK_REGISTER_R9)
.endm
/* Clear the BSS section on start-up */
.macro CLEAR_BSS overwritten_reg1, overwritten_reg2
LOAD_IMMEDIATE \overwritten_reg1, _bss_begin
LOAD_IMMEDIATE \overwritten_reg2, _bss_end
l.sfgeu \overwritten_reg1, \overwritten_reg2
OR1K_DELAYED_NOP (l.bf bss_is_empty)
bss_clear_loop:
/* Possible optimisation to investigate:
move "l.sw 0(\overwritten_reg1), r0" to the jump delay slot as
"l.sw -4(\overwritten_reg1), r0" or similar. But keep in mind that
there are plans to remove the jump delay slot. */
l.sw 0(\overwritten_reg1), r0
l.addi \overwritten_reg1, \overwritten_reg1, 4
l.sfgtu \overwritten_reg2, \overwritten_reg1
OR1K_DELAYED_NOP (l.bf bss_clear_loop)
bss_is_empty:
.endm
#endif /* OR1K_ASM_TEST_H */