mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-27 04:52:05 +08:00
4a94e36819
This commit brings all the changes made by running gdb/copyright.py as per GDB's Start of New Year Procedure. For the avoidance of doubt, all changes in this commits were performed by the script.
227 lines
6.1 KiB
C
227 lines
6.1 KiB
C
/* Testsuite architecture macros for OpenRISC.
|
|
|
|
Copyright (C) 2017-2022 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 */
|