/* VM library: ARM definitions, to be included from both C and assembly.

   Copyright (C) 2017-2021 Luca Saiu
   Copyright (C) 2021 pEp foundation
   Updated in 2022 by Luca Saiu
   Written by Luca Saiu

   This file is part of GNU Jitter.

   GNU Jitter 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.

   GNU Jitter 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 GNU Jitter.  If not, see <https://www.gnu.org/licenses/>. */


#ifndef JITTER_NATIVE_MACHINE_H_ /* One macro suffices for all architectures. */
#define JITTER_NATIVE_MACHINE_H_




/* How to introduce comments in assembly on ARM, at any point within the
   line. */
#define JITTER_ASM_COMMENT_PREFIX                               \
  /* "#" works in some contexts but has other uses as well. */  \
  "@ "




/* Debugging.
 * ************************************************************************** */

/* Expand to an inline assembly template generating a nop instruction containing
   the given literal as an argument. */
#define _JITTER_ASM_DEBUGGING_NOP(integer_literal_as_string)           \
  /* At a quick skim of the ARM documentation I found no better        \
     way.  Is there some way to achieve this with one instruction? */  \
  "eor r1, r1, #" integer_literal_as_string "\n\t"                     \
  "eor r1, r1, #" integer_literal_as_string

/* Expand to a native machine code snippet causing a trap, as a string literal
   in a syntax suitable for extended inline asm. */
#define _JITTER_ASM_CRASH                                              \
  /* Generate a software interrupt with a meaningless argument         \
     and crash, hopefully.                                             \
     Unfortunately I cannot use an obvious alternative such as         \
       rfe r1                                                          \
     because rfe is not to be supported on very old revisions of       \
     the architecture.                                                 \
     The immediate argument should be small enough to fit in the       \
     instruction encoding in Thumb mode. */                            \
  "swi 43"




/* Computed goto.
 * ************************************************************************** */

/* Computed goto implemented with inline asm.  See the comments about
   JITTER_ASM_COMPUTED_GOTO_TEMPLATE, and
   JITTER_ASM_COMPUTED_GOTO_INPUT_CONSTRAINT and
   JITTER_ASM_COMPUTED_GOTO_CLOBBERS in jitter/jitter-executor.h . */
#define JITTER_ASM_COMPUTED_GOTO_TEMPLATE  \
  /* r15 is the program counter. */        \
  "mov r15, %[_jitter_the_target]"
#define JITTER_ASM_COMPUTED_GOTO_INPUT_CONSTRAINT  \
  "r"




/* Reserved registers.
 * ************************************************************************** */

// FIXME: not used yet.

/* The following ARM registers have a special use:
     r13 stack pointer
     r14 link register
     r15 program counter
   The following registers are callee-save in the ABIs supoorted by Jitter and
   suitable to be reserved:
     FIXME: I do not know yet
   */

#endif // #ifndef JITTER_NATIVE_MACHINE_H_
