1 # Copyright (C) 2001-2006, Parrot Foundation.
6 docs/jit.pod - Parrot JIT Subsystem
10 This PDD describes the Parrot Just In Time compilation subsystem.
14 The Just In Time, or JIT, subsystem converts a bytecode file to native machine
15 code instructions and executes the generated instruction sequence directly.
19 Currently works on B<ALPHA>, B<Arm>, B<Intel x86>, B<PPC>, and B<SPARC version
20 8> processor systems, on most operating systems. Currently only 32-bit INTVALs
23 The initial step in generating native code is to invoke B<Parrot_jit_begin>,
24 which generally provides architecture specific preamble code. For each parrot
25 opcode in the bytecode, either a generic or opcode specific sequence of native
26 code is generated. The F<.jit> files provide functions that generate native
27 code for specific opcode functions, for a given instruction set architecture.
28 If a function is not provided for a specific opcode, a generic sequence of
29 native code is output which calls the interpreter C function that implements
30 the opcode. Such opcode are handled by B<Parrot_jit_normal_op>.
32 If the opcode can cause a control flow change, as in the case of a branch or
33 call opcode, an extended or modified version of this generic code is used that
34 tracks changes in the bytecode program counter with changes in the hardware
35 program counter. This type of opcode is handled by B<Parrot_jit_cpcf_op>.
37 While generating native code, certain offsets and absolute addresses may not be
38 available. This occurs with forward opcode branches, as the native code
39 corresponding to the branch target has not yet been generated. On some
40 platforms, function calls are performed using program-counter relative
41 addresses. Since the location of the buffer holding the native code may move
42 as code is generated (due to growing of the buffer), these relative addresses
43 may only be calculated once the buffer is guaranteed to no longer move. To
44 handle these instances, the JIT subsystem uses "fixups", which record locations
45 in native code where adjustments to the native code are required.
51 =item jit/${jitcpuarch}/jit_emit.h
53 This file defines B<Parrot_jit_begin>, B<Parrot_jit_dofixup>,
54 B<Parrot_jit_normal_op>, B<Parrot_jit_cpcf_op>, B<Parrot_jit_restart_op> and
55 optionally B<Parrot_jit_vtable*_op>. In addition, this file defines the macros
56 and static functions used in F<.jit> files to produce binary representations of
59 For moving registers from processor to parrot and vice versa, the
60 B<Parrot_jit_emit_mov*> functions have to be implemented.
62 =item jit/${jitcpuarch}/core.jit
64 The functions to generate native code for core parrot opcodes are specified
65 here. To simplify the maintenance of these functions, they are specified in a
66 format that is pre-processed by F<jit2c.pl> to produce a valid C source file,
67 F<jit_cpu.c>. See L<Format of .jit Files> below.
71 This file contains definitions of generic structures used by the JIT subsystem.
73 The B<op_jit> array of B<jit_fn_info_t> structures, provides for each opcode, a
74 pointer to the function that generates native code for the opcode, whether the
75 generic B<Parrot_jit_normal_op> or B<Parrot_jit_cpcf_op> functions or an opcode
76 specific function. B<Parrot_jit_restart_op> is like B<Parrot_jit_cpcf_op> with
77 the addition to check for a zero program counter. The B<Parrot_jit_vtable*_op>
78 functions are defined as B<Parrot_jit_normal_op> or B<Parrot_jit_cpcf_op> and
79 may be implemented to do native vtable calls (s. F<jit/i386/jit_emit.h> for an
82 The B<Parrot_jit_fixup> structure records the offset in native code where a
83 fixup must be applied, the type of fixup required and the specific information
84 needed to perform the parameters of the fixup. Currently, a fixup parameter is
85 either an B<opcode_t> value or a function pointer.
87 The B<Parrot_jit_info> structure holds data used while producing and executing
88 native code. An important piece of data in this structure is the B<op_map>
89 array, which maps from opcode addresses to native code addresses.
93 B<parrot_build_asm>() is the main routine of the code generator, which loops
94 over the parrot bytecode, calling the code generating routines for each opcode
95 while filling in the B<op_map> array. This array is used by the JIT subsystem
96 to perform certain types of fixups on native code, as well as by the native
97 code itself to convert bytecode program counters values (opcode_t *'s) to
98 hardware program counter values.
100 The bytecode is considered an array of B<opcode_t> sized elements, with
101 parallel entries in B<op_map>. B<op_map> is initially populated with the
102 offsets into the native code corresponding to the opcodes in the bytecode. Once
103 code generation is complete and fixups have been applied, the native code
104 offsets are converted to absolute addresses. This trades the low up-front cost
105 of converting all offsets once, for the unknown cost of repeatedly converting
106 these offsets while executing native code.
108 See F<src/jit/skeleton/jit_emit.h> for details.
110 =item tools/build/jit2c.pl
112 Preprocesses the .jit files to produce F<jit_cpu.c>.
116 =head1 Defines in jit_emit.h
118 The architecture specific F<jit_emit.h> file communicates some defines and
119 tables with F<jit.c> and F<languages/imcc/imc.c>. The structure of the file and
120 the defines must therefore follow a specific syntax.
122 =head2 Overall structure
131 static const jit_arch_info arch_info = {
132 ... initialization of maps
133 ... and possibly private static functions
138 See F<src/jit/skeleton/jit_emit.h> for a more detailed explanation.
142 XXX most are moved into C<jit_arch_info> now.
146 =item INT_REGISTERS_TO_MAP
148 This is the amount of integer registers to be mapped to processor registers.
149 The corresponding B<intval_map[]> has to have exactly this amount of register
150 numbers. A register with the value of zero can not be in the list.
152 =item FLOAT_REGISTERS_TO_MAP
154 When this is defined, it works like above for floating point registers.
156 =item PRESERVED_INT_REGS
158 When this is defined, it's the amount of integer registers, that are preserved
159 over function calls. These preserved registers have to be first in
160 B<intval_map>. When this is not defined, it is assumed that B<all> registers
161 are preserved over function calls.
163 =item PRESERVED_FLOAT_REGS
165 Same for floating point registers.
167 =item jit_emit_noop(pc)
171 If these are defined, B<JUMP_ALIGN> should be a small number stating the
172 desired alignment of jump targets is B<1 << JUMP_ALIGN>. The B<jit_emit_noop>
173 gets called with the unaligned B<pc> repeatedly, until the B<pc> has the
174 desired alignment. So the function can either emit a one byte B<noop>
175 instruction, or a B<noop> like instruction (sequence) with the desired size, to
176 achieve the necessary padding. The emitted code must not have any side
179 =item ALLOCATE_REGISTERS_PER_SECTION
181 Normally F<jit.c> does register allocation per section, but there is a somewhat
182 experimental feature, to allocate registers per basic block.
186 Jit code generated by the F<imcc> JIT optimizer used negative numbers for
187 mapped registers and positive numbers for non mapped parrot registers. To use
188 this feature, the definition of mapped registers can be redefined like so:
190 #define MAP(i) OMAP(i)
192 #define MAP(i) (i) >= 0 ? 0 : OMAP(i)
194 =item Parrot_jit_emit_get_base_reg_no(pc)
196 This macro should return the register number of the register
201 See F<src/jit/i386/jit_emit.h> for actual usage of these defines.
203 =head1 Format of .jit Files
205 Jit files are interpreted as follows:
209 =item I<op-name> { \n I<body> \n }
211 Where I<op-name> is the name of the Parrot opcode, and I<body> consists of C
212 syntax code which may contain any of the identifiers listed in the following
215 The closing curly brace has to be in the first column.
219 Comments are marked with a I<;> in the first column. These and empty lines are
224 In general, prefixing an identifier with I<&> yields an address. The I<*>
225 prefix specifies a value. Since Parrot register values vary during code
226 execution, their values can not be obtained through identifier substitution
227 alone, therefore offsets are used for accessing registers.
229 To obtain register offsets, a set of macros exists, that have C<OFFS> in
232 B<REG_OFFS_INT(reg_no)> ...
238 Gets replaced by the C<INTVAL> constant specified in the I<n>th argument.
242 Gets replaced by the C<FLOATVAL> constant specified in the I<n>th argument.
246 The I<n>th integer or floating processor register, mapped in this section.
248 Note: The register with the physical number zero can not be mapped.
252 B<STRING_CONST_strstart[n]>
254 Gets replaced by C<strstart> of the C<STRING> constant specified in the I<n>th
257 B<STRING_CONST_buflen[n]>
259 Gets replaced by C<buflen> of the C<STRING> constant specified in the I<n>th
262 B<STRING_CONST_flags[n]>
264 Gets replaced by C<flags> of the C<STRING> constant specified in the I<n>th
267 B<STRING_CONST_strlen[n]>
269 Gets replaced by C<strlen> of the C<STRING> constant specified in the I<n>th
272 B<STRING_CONST_encoding[n]>
274 Gets replaced by C<encoding> of the C<STRING> constant specified in the I<n>th
277 B<STRING_CONST_type[n]>
279 Gets replaced by C<type> of the C<STRING> constant specified in the I<n>th
282 B<STRING_CONST_language[n]>
284 Gets replaced by C<language> of the C<STRING> constant specified in the I<n>th
291 Gets replaced by the current native program counter.
295 Gets replaced by the address of the current opcode in the Parrot bytecode.
299 The I<n>th integer or floating point scratch register.
302 =item B<TEMPLATE> I<template-name> { \n I<body> \n }
304 Defines a template for similar functions, e.g. all the binary ops taking three
307 =item I<template-name> I<perl-subst> ...
309 Take a template and do all substitutions to generate the implementation for
314 TEMPLATE Parrot_set_x_ic {
316 jit_emit_mov_ri<_N>(NATIVECODE, MAP[1], <typ>_CONST[2]);
319 jit_emit_mov_mi<_N>(NATIVECODE, &INT_REG[1], <typ>_CONST[2]);
324 Parrot_set_x_ic s/<_N>/_i/ s/<typ>/*INT/
328 Parrot_set_x_ic s/<_N>/_ni/ s/<typ>/&INT/ s/INT_R/NUM_R/
331 The jit function B<Parrot_set_i_ic> is based on the template
332 B<Parrot_set_x_ic>, the I<s/x/y/> are substitutions on the template body, to
333 generate the actual function body. These substitutions are done before the
336 s. F<jit/i386/core.jit> for more.
340 =head2 Naming convention for jit_emit functions
342 To make it easier to share F<core.jit> files between machines of similar
343 architecture, the jit_emit functions B<should> follow this syntax:
345 jit_emit_I<<op>>_I<<args>>_I<<type>>
351 This is the operation like B<mov>, B<add> or B<bxor>. In normal cases this is
352 the PASM name of the op.
356 B<args> specify the arguments of the function in the PASM sequence B<dest>,
357 B<source> ... The B<args> consist of one letter per argument:
363 A mapped processor register.
367 A memory operand, the address of the parrot register.
371 An immediate operand, i.e. an integer constant.
377 Specifies if this operation works on integer or floating point arguments. If
378 all arguments are of the same type, only one type specifier is needed.
396 =item B<jit_emit_sub_rm_i>
398 Subtract integer at memory from integer processor register.
400 =item B<jit_emit_mov_ri_ni>
402 Move integer constant (immediate) to floating point register.
410 The access to Parrot registers is done relative to C<$6>, all other memory
411 access is done relative to C<$27>, to access float constants relative to C<$7>
412 so you must preside the instruction with I<ldah $7,0($27)>.
416 Only 32 bit INTVALs are supported. Long double FLOATVALs are ok.
418 There are four mapped integer registers B<%edi>, B<%esi>, B<%ecx>, and B<%edx>.
419 The first 2 of these are callee saved, they preserve their value around extern
422 Four floating point operations the registers B<ST1> ... B<ST4> are mapped and
423 considered as preserved over function calls.
425 The register C<%ebx> holds the register frame pointer.
429 Let's see how this works:
438 B<Parrot Bytecode:> (only the bytecode segment is shown)
440 +--------------------------------------+
441 | 73 | 0 | 8 | 72 | 2 | 0 | 21 | 2 | 0 |
442 +-|------------|------------|--------|-+
444 | | | +----------- end (no arguments)
445 | | +-------------------- print_i (1 argument)
446 | +--------------------------------- set_i_i (2 arguments)
447 +---------------------------------------------- set_i_ic (2 arguments)
449 Please note that the opcode numbers used might have already changed. Also
450 generated assembly code might be different.
452 B<Intel x86 assembly version of the Parrot ops:>
456 0x817ddd0 <jit_func>: push %ebp
457 0x817ddd1 <jit_func+1>: mov %esp,%ebp
458 0x817ddd3 <jit_func+3>: push %ebx
459 0x817ddd4 <jit_func+4>: push %esi
460 0x817ddd5 <jit_func+5>: push %edi
462 normal function header till here, now push interpreter
464 0x817ddd6 <jit_func+6>: push $0x8164420
466 get jit function table to %ebp and
467 jump to first instruction
469 0x817dddb <jit_func+11>: mov 0xc(%ebp),%eax
470 0x817ddde <jit_func+14>: mov $0x81773f0,%ebp
471 0x817dde3 <jit_func+19>: sub $0x81774a8,%eax
472 0x817dde9 <jit_func+25>: jmp *%ds:0x0(%ebp,%eax,1)
476 0x817ddee <jit_func+30>: mov $0x8,%edi
480 0x817ddf3 <jit_func+35>: mov %edi,%ebx
482 B<Parrot_jit_save_registers>
484 0x817ddf5 <jit_func+37>: mov %edi,0x8164420
485 0x817ddfb <jit_func+43>: mov %ebx,0x8164428
487 B<Parrot_jit_normal_op>
489 0x817de01 <jit_func+49>: push $0x81774c0
490 0x817de06 <jit_func+54>: call 0x804be00 <Parrot_print_i>
491 0x817de0b <jit_func+59>: add $0x4,%esp
495 0x817de0e <jit_func+62>: add $0x4,%esp
496 0x817de14 <jit_func+68>: pop %edi
497 0x817de16 <jit_func+70>: pop %ebx
498 0x817de18 <jit_func+72>: pop %esi
499 0x817de1a <jit_func+74>: pop %ebp
500 0x817de1c <jit_func+76>: ret
502 Please note the reverse argument direction. PASM and JIT notations use
503 I<dest,src,src>, while F<gdb> and the internal macros in F<jit_emit.h> have
508 Above listing was generated by F<gdb>, the GNU debugger, with a little help
509 from Parrot_jit_debug, which generates a symbol file in I<stabs> format, s.
510 B<info stabs> for more (or less :-()
512 The following script calls F<ddd> (the graphic debugger fronted) and attaches
513 the symbol file, after it got built in F<parrot_build_asm>.
516 # run ddd parrot with given file
517 # gdb confirmations should be off
518 parrot -o $1.pbc -d1 $1.pasm
522 add-symbol-file $1.o 0
526 ddd --command .ddd parrot &
528 Run this with e.g. I<dddp t/op/jit_2>, then turn on the register status,
529 I<step> or I<nexti> through the source, or set break points as with any other
532 You can examine parrot registers via the debugger or even set them and you can
533 always step into external opcode and look at I<*interpreter>.
535 The tests F<t/op/jit*.t> have some test cases for testing register allocation.
536 These tests are written for a mapping of 4 processor registers. If your
537 processor architecture has more mapped registers, reduce them to 4 and run
540 =head2 Example for a debug session
550 (ddd shows above source code and assembly (startup code snipped):
552 0x815de46 <jit_func+30>: mov $0xa,%ebx
553 0x815de4b <jit_func+35>: fldl 0x81584c0
554 0x815de51 <jit_func+41>: fstp %st(2)
555 0x815de53 <jit_func+43>: mov %ebx,0x8158098
556 0x815de59 <jit_func+49>: fld %st(1)
557 0x815de5b <jit_func+51>: fstpl 0x8158120
558 0x815de61 <jit_func+57>: push $0x815cd90
559 0x815de66 <jit_func+62>: call 0x804db90 <Parrot_set_s_sc>
560 0x815de6b <jit_func+67>: add $0x4,%esp
561 0x815de6e <jit_func+70>: push $0x815cd9c
562 0x815de73 <jit_func+75>: call 0x804bcd0 <Parrot_print_sc>
563 0x815de78 <jit_func+80>: add $0x4,%esp
564 0x815de7b <jit_func+83>: add $0x4,%esp
565 0x815de81 <jit_func+89>: pop %edi
566 0x815de83 <jit_func+91>: pop %ebx
567 0x815de85 <jit_func+93>: pop %esi
568 0x815de87 <jit_func+95>: pop %ebp
569 0x815de89 <jit_func+97>: ret
576 $2 = 1.1000000000000001
578 $3 = {bufstart = 0x815ad30, buflen = 15, flags = 336128, bufused =
579 3, strstart = 0x815ad30 "abc"}
581 $4 = (INTVAL *) 0x8158098
583 XXX (p)rinting register contents like shown above is currently not supported.
587 F<docs/dev/jit_i386.pod>, F<jit/skeleton/jit_emit.h>