[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 36/437: update manual for jit_allocai
From: |
Andy Wingo |
Subject: |
[Guile-commits] 36/437: update manual for jit_allocai |
Date: |
Mon, 2 Jul 2018 05:13:40 -0400 (EDT) |
wingo pushed a commit to branch lightning
in repository guile.
commit f748b3c5e76a2fe87cf4cf906335c55499fded3b
Author: Paolo Bonzini <address@hidden>
Date: Mon Nov 20 12:59:13 2006 +0000
update manual for jit_allocai
git-archimport-id: address@hidden/lightning--stable--1.2--patch-38
---
NEWS | 4 ++
doc/porting.texi | 12 ++----
doc/using.texi | 123 ++++++++++++++++++++++++++++++++++++++-----------------
3 files changed, 92 insertions(+), 47 deletions(-)
diff --git a/NEWS b/NEWS
index 9292f12..e6e7d9f 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,10 @@ o Initial support for x86-64 back-end.
o Many bug fixes.
+o jit_pushr/jit_popr are deprecated, you need to #define
+ JIT_NEED_PUSH_POP prior to including lightning.h if you
+ want to use them.
+
o Support for stack-allocated variables. Because of this,
backends defining JIT_FP should now rename it to JIT_AP.
JIT_FP is now a user-visible register used in ldxi/ldxr
diff --git a/doc/porting.texi b/doc/porting.texi
index 4608587..1cc2a11 100644
--- a/doc/porting.texi
+++ b/doc/porting.texi
@@ -858,7 +858,7 @@ operations:
@section Macros composing the platform-independent layer
@table @b
address@hidden Register names (all mandatory but the last two)
address@hidden Register names (all mandatory but the last three)
@example
#define JIT_R
#define JIT_R_NUM
@@ -866,6 +866,7 @@ operations:
#define JIT_V_NUM
#define JIT_FPR
#define JIT_FPR_NUM
+#define JIT_FP
#define JIT_SP
#define JIT_AP
#define JIT_RZERO
@@ -878,6 +879,7 @@ operations:
@item Mandatory:
@example
+#define jit_allocai()
#define jit_arg_c()
#define jit_arg_i()
#define jit_arg_l()
@@ -1022,11 +1024,9 @@ operations:
#define jit_orr_i(d, s1, s2)
#define jit_patch_at(jump_pc, value)
#define jit_patch_movi(jump_pc, value)
-#define jit_pop_i(rs)
#define jit_prepare_d(numargs)
#define jit_prepare_f(numargs)
#define jit_prepare_i(numargs)
-#define jit_push_i(rs)
#define jit_pusharg_i(rs)
#define jit_ret()
#define jit_retval_i(rd)
@@ -1242,10 +1242,6 @@ operations:
#define jit_ori_ul(d, rs, is)
#define jit_orr_ui(d, s1, s2)
#define jit_orr_ul(d, s1, s2)
-#define jit_pop_ui(rs)
-#define jit_pop_ul(rs)
-#define jit_push_ui(rs)
-#define jit_push_ul(rs)
#define jit_pusharg_c(rs)
#define jit_pusharg_p(rs)
#define jit_pusharg_s(rs)
@@ -1478,8 +1474,6 @@ operations:
#define jit_ner_l(d, s1, s2)
#define jit_ori_l(d, rs, is)
#define jit_orr_l(d, s1, s2)
-#define jit_pop_l(rs)
-#define jit_push_l(rs)
#define jit_pusharg_l(rs)
#define jit_retval_l(rd)
#define jit_rshi_l(d, rs, is)
diff --git a/doc/using.texi b/doc/using.texi
index 3a8578a..af13901 100644
--- a/doc/using.texi
+++ b/doc/using.texi
@@ -90,10 +90,9 @@ is equivalent to @code{i} on 32-bit machines, and @code{p} is
substantially equivalent to @code{ul}).
There are at least seven integer registers, of which six are
-general-purpose, while the last is used to contain the stack pointer
-(@code{SP}). The stack pointer can be used to allocate and access local
-variables on the stack (which is supposed to grow downwards in memory
-on all architectures).
+general-purpose, while the last is used to contain the frame pointer
+(@code{FP}). The frame pointer can be used to allocate and access local
+variables on the stack, using the @code{allocai} instruction.
Of the general-purpose registers, at least three are guaranteed to be
preserved across function calls (@code{V0}, @code{V1} and
@@ -271,15 +270,6 @@ stxr c uc s us i ui l ul p f d *(O1+O2) = O3
stxi c uc s us i ui l ul p f d *(O1+O2) = O3
@end example
address@hidden Stack management
-These accept a single register parameter. These operations are not
-guaranteed to be efficient on all architectures.
-
address@hidden
-pushr i ui l ul p @r{push address@hidden on the
stack}
-popr i ui l ul p @r{pop address@hidden off the
stack}
address@hidden example
-
@item Argument management
These are:
@example
@@ -388,16 +378,13 @@ These accept one argument except @code{ret} which has
none; the
difference between @code{finish} and @code{calli} is that the
latter does not clean the stack from pushed parameters (if any)
and the former must @strong{always} follow a @code{prepare}
-instruction. Results are undefined when using function calls
-in a leaf function.
+instruction.
@example
calli (not specified) @r{function call to O1}
callr (not specified) @r{function call to a register}
finish (not specified) @r{function call to O1}
finishr (not specified) @r{function call to a register}
jmpi/jmpr (not specified) @r{unconditional jump to O1}
-prolog (not specified) @r{function prolog for O1 args}
-leaf (not specified) @r{the same for leaf functions}
ret (not specified) @r{return from subroutine}
retval c uc s us i ui l ul p f d @r{move return value}
@r{to register}
@@ -407,6 +394,26 @@ Like branch instruction, @code{jmpi} also returns a value
which is to
be used to compile forward branches. @xref{Fibonacci, , Fibonacci
numbers}.
address@hidden Function prolog
+
+These macros are used to set up the function prolog, in particular to
+declare the number of arguments accepted by a function, and to reserve
+space on the stack to be used for variables. They accept a single
+numeric argument.
+
address@hidden
+prolog (not specified) @r{function prolog for O1 args}
+leaf (not specified) @r{the same for leaf functions}
+allocai (not specified) @r{reserve space on the stack}
address@hidden example
+
+Results are undefined when using function calls in a leaf function.
+
address@hidden receives the number of bytes to allocate and returns
+the offset from the frame pointer register @code{FP} to the base of
+the area. The area is aligned to an @code{int}; future versions of
address@hidden may provide more fine-grained control on the alignment of
+stack-allocated variables.
@end table
As a small appetizer, here is a small function that adds 1 to the input
@@ -740,39 +747,72 @@ and is able to compile different formulas to different
functions.
Here is the code for the expression compiler; a sample usage will
follow.
+Since @lightning{} does not provide push/pop instruction, this
+example uses a stack-allocated area to store the data. Such an
+area can be allocated using the macro @code{jit_allocai}, which
+receives the number of bytes to allocate and returns the offset
+from the frame pointer register @code{JIT_FP} to the base of the
+area. The area is aligned to an @code{int}; future versions
+of @lightning{} may provide more fine-grained control on the
+alignment of stack-allocated variables.
+
+Usually, you will use the @code{ldxi} and @code{stxi} instruction
+to access stack-allocated variables. However, it is possible to
+use operations such as @code{add} to compute the address of the
+variables, and pass the address around.
+
@example
#include <stdio.h>
#include "lightning.h"
typedef int (*pifi)(int); @rem{/* Pointer to Int Function of Int */}
+void stack_push(int reg, int *sp)
+{
+ jit_stxi_i (*sp, JIT_FP, reg);
+ *sp += sizeof (int);
+}
+
+void stack_pop(int reg, int *sp)
+{
+ *sp -= sizeof (int);
+ jit_ldxi_i (reg, JIT_FP, *sp);
+}
+
pifi compile_rpn(char *expr)
@{
pifi fn;
+ int stack_base, stack_ptr;
int in;
+
fn = (pifi) (jit_get_ip().iptr);
jit_leaf(1);
in = jit_arg_i();
- jit_getarg_i(JIT_R0, in);
+ stack_ptr = stack_base = jit_allocai (32 * sizeof (int));
+
+ jit_getarg_i(JIT_R2, in);
while (*expr) @{
char buf[32];
int n;
if (sscanf(expr, "%[0-9]%n", buf, &n)) @{
expr += n - 1;
- jit_push_i(JIT_R0);
+ stack_push(JIT_R0, &stack_ptr);
jit_movi_i(JIT_R0, atoi(buf));
+ @} else if (*expr == 'x') @{
+ stack_push(JIT_R0, &stack_ptr);
+ jit_movi_i(JIT_R0, JIT_R2);
@} else if (*expr == '+') @{
- jit_pop_i(JIT_R1);
+ stack_pop(JIT_R1, &stack_ptr);
jit_addr_i(JIT_R0, JIT_R1, JIT_R0);
@} else if (*expr == '-') @{
- jit_pop_i(JIT_R1);
+ stack_pop(JIT_R1, &stack_ptr);
jit_subr_i(JIT_R0, JIT_R1, JIT_R0);
@} else if (*expr == '*') @{
- jit_pop_i(JIT_R1);
+ stack_pop(JIT_R1, &stack_ptr);
jit_mulr_i(JIT_R0, JIT_R1, JIT_R0);
@} else if (*expr == '/') @{
- jit_pop_i(JIT_R1);
+ stack_pop(JIT_R1, &stack_ptr);
jit_divr_i(JIT_R0, JIT_R1, JIT_R0);
@} else @{
fprintf(stderr, "cannot compile: %s\n", expr);
@@ -786,13 +826,20 @@ pifi compile_rpn(char *expr)
@}
@end example
-The principle on which the calculator is based is easy: the stack
-top is held in R0, while the remaining items of the stack are held
-on the hardware stack. Compiling an operand pushes the old stack
-top onto the stack and moves the operand into R0; compiling an
-operator pops the second operand off the stack into R1, and
-compiles the operation so that the result goes into R0, thus
-becoming the new stack top.
+The principle on which the calculator is based is easy: the stack top
+is held in R0, while the remaining items of the stack are held in the
+memory area that we allocate with @code{allocai}. Compiling a numeric
+operand or the argument @code{x} pushes the old stack top onto the
+stack and moves the operand into R0; compiling an operator pops the
+second operand off the stack into R1, and compiles the operation so
+that the result goes into R0, thus becoming the new stack top.
+
+This example allocates a fixed area for 32 @code{int}s. This is not
+a problem when the function is a leaf like in this case; in a full-blown
+compiler you will want to analyze the input and determine the number
+of needed stack slots---a very simple example of register allocation.
+The area is then managed like a stack using @code{stack_push} and
address@hidden
Try to locate a call to @code{jit_set_ip} in the source code. You
will not find one; this means that the client has to manually set
@@ -814,8 +861,8 @@ int main()
int i;
jit_set_ip(codeBuffer);
- c2f = compile_rpn("9*5/32+");
- f2c = compile_rpn("32-5*9/");
+ c2f = compile_rpn("32x9*5/+");
+ f2c = compile_rpn("x32-5*9/");
jit_flush_code(codeBuffer, jit_get_ip().ptr);
printf("\nC:");
@@ -845,9 +892,9 @@ generation so powerful.
The @file{rpn.c} file in the @lightning{} distribution includes a more
complete (and more complex) implementation of @code{compile_rpn},
-which does constant folding, allows the argument to the functions
-to be used more than once, and is able to assemble instructions with
-an immediate parameter.
+which does constant folding and is able to assemble instructions with
+an immediate parameter. Still, it is based on the same principle and
+also uses @code{allocai} to allocate space for the stack.
@node Fibonacci
@section Fibonacci numbers
@@ -1160,9 +1207,9 @@ extern void _opt_muli_i(struct jit_state *, int, int,
int);
@section Registers
@chapter Accessing the whole register file
-As mentioned earlier in this chapter, all @lightning{} back-ends
-are guaranteed to have at least six integer registers and six
-floating-point registers, but many back-ends will have more.
+As mentioned earlier in this chapter, all @lightning{} back-ends are
+guaranteed to have at least six general-purpose integer registers and
+six floating-point registers, but many back-ends will have more.
To access the entire register files, you can use the
@code{JIT_R}, @code{JIT_V} and @code{JIT_FPR} macros. They
- [Guile-commits] 24/437: bump version, add ldxi test case, (continued)
- [Guile-commits] 24/437: bump version, add ldxi test case, Andy Wingo, 2018/07/02
- [Guile-commits] 30/437: added ret test and clarified JIT_RET documentation, Andy Wingo, 2018/07/02
- [Guile-commits] 20/437: fix PPC modi, Andy Wingo, 2018/07/02
- [Guile-commits] 35/437: remove pushr/popr from testsuite, Andy Wingo, 2018/07/02
- [Guile-commits] 31/437: prepare for automatic variables support, Andy Wingo, 2018/07/02
- [Guile-commits] 29/437: cherrypick from ludovic courtes, Andy Wingo, 2018/07/02
- [Guile-commits] 33/437: add jit_allocai for SPARC, Andy Wingo, 2018/07/02
- [Guile-commits] 16/437: Fix comments in config.h.in git-archimport-id: address@hidden/lightning--stable--1.2--patch-18, Andy Wingo, 2018/07/02
- [Guile-commits] 37/437: fix x86-64 builds, Andy Wingo, 2018/07/02
- [Guile-commits] 42/437: add an underscore to macros without a parameter [x86], Andy Wingo, 2018/07/02
- [Guile-commits] 36/437: update manual for jit_allocai,
Andy Wingo <=
- [Guile-commits] 46/437: merge from ludovic, Andy Wingo, 2018/07/02
- [Guile-commits] 14/437: update FSF address, Andy Wingo, 2018/07/02
- [Guile-commits] 34/437: finish jit_allocai implementation, Andy Wingo, 2018/07/02
- [Guile-commits] 43/437: give credit to whom credit is due, Andy Wingo, 2018/07/02
- [Guile-commits] 41/437: x86-64 now passes test suite, Andy Wingo, 2018/07/02
- [Guile-commits] 47/437: refine ludovic's doc patch, Andy Wingo, 2018/07/02
- [Guile-commits] 38/437: add JIT_NEED_PUSH_POP and merge correct implementation of push/pop for SPARC, Andy Wingo, 2018/07/02
- [Guile-commits] 50/437: fix imprecisions in the ChangeLog, Andy Wingo, 2018/07/02
- [Guile-commits] 48/437: use CVTT instruction, fix lightning/Makefile.am, Andy Wingo, 2018/07/02
- [Guile-commits] 53/437: fix -I flags for opcode subdirectory, Andy Wingo, 2018/07/02