1/* VM library: macros to be optionally included in architecture-specific asm.
2
3   Copyright (C) 2017, 2019 Luca Saiu
4   Updated in 2020 by Luca Saiu
5   Written by Luca Saiu
6
7   This file is part of Jitter.
8
9   Jitter is free software: you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation, either version 3 of the License, or
12   (at your option) any later version.
13
14   Jitter is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with Jitter.  If not, see <http://www.gnu.org/licenses/>. */
21
22
23/* This is an assembly file independent from the architecture, containing Gas
24   macros to be optionally used (by CPP inclusion) in the architecture-specific
25   file machine/ARCHITECTURE/jitter/machine/jitter-machine-assembly.S .
26
27   The macros defined here are meant to be called from the .text section.
28
29   This file contains macro definitions only, and by itself generates nothing
30   except possibly possibly a .note.GNU-stack section.
31   Because of this this file is also safe to include as a source in Makefile.am
32   , so that make can automatically discover dependencies. */
33
34#ifndef MACHINE_COMMON_S_
35#define MACHINE_COMMON_S_
36
37
38/* Include feature macros.
39 * ************************************************************************** */
40
41/* The code from this header defines macros but expands to nothing except
42   possibly a .note.GNU-stack section, so it is safe to include from assembly
43   as well. */
44#include <jitter/jitter-config.h>
45
46/* We use CPP token concatenation here.  The header contains CPP macro
47   definitions only, and is safe to use from assembly. */
48#include <jitter/jitter-cpp.h>
49
50
51/* Expand to nothing if we have no assembly support.
52 * ************************************************************************** */
53
54/* If in this configuration the assembler is not Gas or we do not know its
55   syntax or either configure or the user has decided to disable assembly
56   support, for any reason, expand the rest of this file to whitespace only. */
57
58#if defined (JITTER_HAVE_ASSEMBLY) && defined (JITTER_HAVE_KNOWN_BINARY_FORMAT)
59
60/* If we arrived here we can acually use assembly. */
61
62
63
64
65/* Global GNU Assembler settings and definitions.
66 * ************************************************************************** */
67
68/* I like the & separator and <> quoting. */
69.altmacro
70
71
72
73
74/* Machine dependencies.
75 * ************************************************************************** */
76
77/* FIXME: factor with jitter.h . */
78#if   JITTER_SIZEOF_VOID_P == 8
79# define jitter_asm_word .quad
80#elif JITTER_SIZEOF_VOID_P == 4
81# define jitter_asm_word .long
82#elif JITTER_SIZEOF_VOID_P == 2
83# define jitter_asm_word .word
84# warning "Weird: running Jitter on a 16-bit machine; this is untested."
85#else
86# error "Weird: this machine's word size is not 8, 4 or 2 bytes"
87#endif // #if JITTER_SIZEOF_VOID_P == ...
88
89
90
91
92/* Stack executability not required.
93 * ************************************************************************** */
94
95/* Do not require an executable stack.  Jitter, or a Jittery VM runtime, never
96   directly relies on that.
97
98   Rationale: none of my assembly code relies on executable stacks, even if GCC
99   assumes, by default, that an assembly source file does.  Since this file is
100   included in every assembly source this is a good place to put this.  If some
101   other source linked to the Jitter runtime requires an executable stack then
102   the linked executable will have it, thanks to another
103     .section .note.GNU-stack, "x", @progbits
104   written somewhere else.
105   The Jitter runtime itself, along with every example in the distribution,
106   could easily be compiled and linked with
107     -Wa,--noexecstack -Wl,-z,noexecstack
108   , if there were nothing else. */
109#if defined (JITTER_HOST_OS_IS_ELF) \
110    && defined (JITTER_HAVE_SECTION_NOTE_GNU_STACK)
111.section .note.GNU-stack, "", @progbits
112.previous
113#endif // defined (JITTER_HOST_OS_IS_ELF) && ...
114
115
116
117
118/* Switching sections.
119 * ************************************************************************** */
120
121/* The macros defined in the rest of this file are called from a .text section.
122
123   This assumption is important on weak binary formats for which the GNU
124   Assembler does not support a section stack; when done with emitting output
125   for a non-default section we can return to the previous stream with .text
126   instead of a non-portable directive such as .popsection .  The full power of
127   a subsection stack is not used here.
128
129   These definitions should be simple and general enough to work on any platform
130   where Gas works, with no conditionalization. */
131
132/* Enter the given subsection in the named section (initial dot included). */
133.macro jitter_asm_enter_section section, subsection
134  \section \subsection
135.endm
136
137/* Exit the current subsection and change to .text. */
138.macro jitter_asm_exit_section
139  .text
140.endm
141
142
143
144
145/* Global definitions.
146 * ************************************************************************** */
147
148/* The definitions here are format-specific.  I know of no general way of
149   emitting global definitions working on every format. */
150
151/* Here the defined global may require an "_" prefix,
152   .def .. .endef , and no .type .
153   About the word size kludge, it may not be very portable.  Still, the only
154   widely used COFF systems are supported this way, and even this effort is
155   more than those systems deserve.
156   FIXME: possibly factor with jitter/jitter-sections.h . */
157#if JITTER_SIZEOF_VOID_P == 8
158# define JITTER_ASM_WITH_COFF_GLOBAL_PREFIX(identifier) \
159  identifier
160#else
161# define JITTER_ASM_WITH_COFF_GLOBAL_PREFIX(identifier) \
162  JITTER_CONCATENATE_TWO(_, identifier)
163#endif // word size
164
165
166/* Open the definition of a global with the given name, without changing
167   section.  Generate a label with the given name. */
168.macro jitter_global_begin name
169#if defined (JITTER_HOST_OS_IS_ELF)
170        .balign 16
171        .globl \name
172        .type \name, STT_OBJECT
173\name:
174#elif defined (JITTER_HOST_OS_IS_COFF)
175        .balign 16
176        .globl \name
177  .def JITTER_ASM_WITH_COFF_GLOBAL_PREFIX(\name); .scl 2; .type 32;
178  .endef
179JITTER_ASM_WITH_COFF_GLOBAL_PREFIX(\name):
180#else
181# error "unsupported binary format: this configuration should not use assembly"
182#endif // binary format conditional
183.endm
184
185/* Close the definition of a global with the given name, without changing
186   section. */
187.macro jitter_global_end name
188#if defined (JITTER_HOST_OS_IS_ELF)
189  /* Nothing needed. */
190#elif defined (JITTER_HOST_OS_IS_COFF)
191  /* Nothing needed. */
192#else
193# error "unsupported binary format: this configuration should not use assembly"
194#endif // binary format conditional
195.endm
196
197
198
199
200/* Arrays.
201 * ************************************************************************** */
202
203/* Declare the jitter_native_snippet_sizes symbol in the .data subsection 1,
204   the jitter_native_snippet_pointers symbol in the .data subsection 2 and the
205   jitter_native_snippet_names symbol in the .data subsection 3 (also using the
206   .data subsection 4 to store internal data); by using the Gas macro
207   jitter_snippet the subsections will be filled, respectively, with word-sized
208   (in the Jitter sense) elements holding the size of each snippet and with
209   word-sized elements (again in the Jitter sense) holding pointers to the
210   beginning of each snippet, and with pointers (again Jitter-word-sized) to
211   snippet names as strings.
212   Every array element is added in the order of jitter_snippet calls.  The three
213   symbols will be visible from C as objects of type const jitter_uint [],
214   const char * const [] and const char* const [], which will be convenient
215   for implementing jitter_snippet_size, jitter_snippet_code and jitter_snippet_name .
216   The three arrays are meant to be indexed with enum jitter_snippet_to_patch
217   objects, whose cases must follow the same order as the jitter_native calls
218   here. */
219.macro jitter_arrays
220/* Define the array jitter_native_snippet_sizes in .data subsection 1 , making it
221   visible from C. */
222jitter_asm_enter_section .data, 1
223  jitter_global_begin jitter_native_snippet_sizes
224jitter_asm_exit_section
225/* Define the array jitter_native_snippet_pointers in .data subsection 2 , making
226   it visible from C. */
227jitter_asm_enter_section .data, 2
228  jitter_global_begin jitter_native_snippet_pointers
229jitter_asm_exit_section
230/* Define the array jitter_native_snippet_names in .data subsection 3 , making it
231   visible from C. */
232jitter_asm_enter_section .data, 3
233  jitter_global_begin jitter_native_snippet_names
234jitter_asm_exit_section
235.endm
236
237/* A simple Gas macro emitting the given label with the prefix "jitter_native_",
238   followed by up to twenty instructions (or generically "lines"), plus
239   a Jitter-word-sized datum with the same name as the function followed by
240   "_size" holding the snippet size in bytes. */
241.macro jitter_snippet snippet_name, \
242                  insn1, insn2=<>, insn3=<>, insn4=<>, insn5=<>, insn6=<>, \
243                  insn7=<>, insn8=<>, insn9=<>, insn10=<>, insn11=<>, insn12=<>, \
244                  insn13=<>, insn14=<>, insn15=<>, insn16=<>, insn17=<>, \
245                  insn18=<>, insn19=<>, insn20=<>
246/* Emit the snippet in the current section.  Use an alignment sufficient for
247   all architectures; Gas refuses to emit misaligned instructions on some
248   platforms. */
249        .balign 16
250jitter_native_&\snippet_name&:
251        \insn1
252        \insn2
253        \insn3
254        \insn4
255        \insn5
256        \insn6
257        \insn7
258        \insn8
259        \insn9
260        \insn10
261        \insn11
262        \insn12
263        \insn13
264        \insn14
265        \insn15
266        \insn16
267        \insn17
268        \insn18
269        \insn19
270        \insn20
271jitter_native_&\snippet_name&_end:
272/* Add a word-sized datum containing the procedure size in .data subsection 1 ;
273   it will be one element of jitter_native_snippet_sizes . */
274jitter_asm_enter_section .data, 1
275        jitter_asm_word (jitter_native_&\snippet_name&_end - jitter_native_&\snippet_name&)
276jitter_asm_exit_section
277/* Add a datum containing a pointer to the snippet beginning in .data
278   subsection 2 . */
279jitter_asm_enter_section .data, 2
280        jitter_asm_word jitter_native_&\snippet_name
281jitter_asm_exit_section
282/* Add a datum containing the procedure name in .data subsection 4 . */
283jitter_asm_enter_section .data, 4
284        jitter_native_&\snippet_name&_name:
285        .ascii "\snippet_name"
286        .byte 0x0
287jitter_asm_exit_section
288/* Add a datum containing a pointer to the the procedure name in .data
289   subsection 3 . */
290jitter_asm_enter_section .data, 3
291        jitter_asm_word jitter_native_&\snippet_name&_name
292jitter_asm_exit_section
293.endm
294
295#endif // #if defined (JITTER_HAVE_ASSEMBLY) && defined (JITTER_HAVE_KNOWN_BINARY_FORMAT)
296
297#endif // #ifndef MACHINE_COMMON_S_
298