# Copyright (C) 2001-2004, The Perl Foundation.
# $Id: pdd06_pasm.pod 14308 2006-08-22 17:14:31Z ambs $

=head1 NAME

docs/pdds/pdd06_pasm.pod - Parrot Assembly Language

=head1 ABSTRACT

This PDD describes the format of Parrot's bytecode assembly language.

=head1 DESCRIPTION

Parrot's bytecode can be thought of as a form of machine language for a virtual
super CISC machine. It makes sense, then, to define an assembly language for it
for those people who may need to generate bytecode directly, rather than
indirectly via the perl (or any other) language.

{{ NOTE: out-of-date and incomplete. It seems that it would be more
useful as a specification of the format of PASM than as a comprehensive
listing of all opcodes. }}

=head1 IMPLEMENTATION

Parrot opcodes take the format of:

  code destination[dest_key], source1[source1_key], source2[source2_key]

The brackets do not denote optional arguments as such--they are real brackets.
They may be left out entirely, however. If any argument has a key the assembler
will substitute the null key for arguments missing keys.

Conditional branches take the format:

  code boolean[bool_key], true_dest

The key parameters are optional, and may be either an integer or a string. If
either is passed they are associated with the parameter to their left, and are
assumed to be either an array/list entry number, or a hash key. Any time a
source or destination can be a PMC register, there may be a key.

Destinations for conditional branches are an integer offset from the current
PC.

All registers have a type prefix of P, S, I, or N, for PMC, string, integer,
and number respectively.

=head1 Assembly Syntax

All assembly opcodes contain only ASCII lowercase letters, digits, and the
underscore.

Upper case names are reserved for assembler directives. {{ NOTE: no
longer true. }}

Labels all end with a colon. They may have ASCII letters, numbers, and
underscores in them. Labels that begin with a dollar sign (the only valid spot
in a label a dollar sign can appear) are private to the subroutine they appear
in.

Namespaces are noted with the C<.namespace> directive. It takes a
single parameter, the name of the namespace, in the form of a
multi-dimensional key.

Subroutine names are noted with the C<.sub> directive. It takes a
single parameter, the name of the subroutine, which is added to the
namespace's symbol table. Sub names may be any valid Unicode
alphanumeric character and the underscore.

Constants don't need to be named and put in a separate section of the assembly
source. The assembler will take care of putting them in the appropriate part of
the generated bytecode.


=head1 OPCODE LIST

In the following list, there may be multiple (but unlisted) versions of an
opcode. If an opcode takes a register that might be keyed, the keyed version of
the opcode has a _k suffix. If an opcode might take multiple types of registers
for a single parameter, the opcode function really has a _x suffix, where x is
either P, S, I, or N, depending on whether a PMC, string, integer, or numeric
register is involved. The suffix isn't necessary (though not an error) as the
assembler can intuit the information from the code.

In those cases where an opcode can take several types of registers, and more
than one of the sources or destinations are of variable type, then the register
is passed in extended format. An extended format register number is of the
form:

     register_number | register_type

where register_type is 0x100, 0x200, 0x400, or 0x800 for PMC, string, integer,
or number respectively. So N19 would be 0x413.

B<Note>: Instructions tagged with a * will call a vtable method to handle the
instruction if used on PMC registers.

In all cases, the letters x, y, and z refer to register numbers. The letter t
refers to a generic register (P, S, I, or N). A lowercase p, s, i, or n means
either a register or constant of the appropriate type (PMC, string, integer, or
number)

=head2 Control flow

The control flow opcodes check conditions and manage program flow.

=over 4

=item if tx, ix

Check register tx. If true, branch by X.

=item unless tx, ix

Check register tx. If false, branch by X.

=item jump tx

Jump to the address held in register x (Px, Sx, or Ix).

=item branch tx

Branch forward or backward by the amount in register x. (X may be either Ix,
Nx, or Px) Branch offset may also be an integer constant.

=item jsr tx

Jump to the location specified by register X. Push the current location onto
the call stack for later returning.

=item bsr ix

Branch to the location specified by X (either register or label). Push the
current location onto the call stack for later returning.

=item ret

Pop the location off the top of the stack and go there.

=back

=head2 Data manipulation

These ops handle manipulating the data in registers

=over 4

=item new Px, iy

Create a new PMC of class y stored in PMC register x.

=item destroy Px

Destroy the PMC in register X, leaving it undef

=item set tx, ty

Copies y into x. Note that strings and PMCs are referred to by pointer, so if
you do something like:

   set S0, S1

this will copy the pointer in S1 into S0, leaving B<both> registers pointing at
the same string.

=item exchange tx, ty

Exchange the contents of registers X and Y, which must be of the same type.
(Generally cheaper than using the stack as an intermediary when setting up
registers for function calls)

=item assign Px, ty

Takes the contents of Y and assigns them into the existing PMC in X.

While set just copies pointers from one register to another, assign actually
does a value assignment, as:

    $foo = $bar;

X's assign vtable method is invoked and it does whatever is appropriate.

=item clone Px, Py

=item clone Sx, xy

Performs a "deeper" copy of y into x, using the vtable appropriate to the class
of Py if cloning a PMC.

=item tostring Sx, ty, Iz

Take the value in register y and convert it to a string of type z, storing the
result in string register x.

=item add tx, ty, tz *

Add registers y and z and store the result in register x. (x = y + z) The
registers must all be the same type, PMC, integer, or number.

=item sub tx, ty, tz *

Subtract register z from register y and store the result in register x. (x = y
- z) The registers must all be the same type, PMC, integer, or number.

=item mul tx, ty, tz *

Multiply register y by register z and store the results in register x. The
registers must be the same type.

=item div tx, ty, tz *

Divide register y by register z, and store the result in register x.

=item inc tx, nn *

Increment register x by nn. nn is an integer constant. If nn is omitted,
increment is 1.

=item dec tx, nn *

Decrement register x by nn. nn is an integer constant. If nn is omitted,
decrement by 1.

=item length Ix, Sy

Put the length of string y into integer register x.

=item concat Sx, Sy

Add string y to the end of string x.

=item repeat Sx, Sy, iz

Copies string y z times into string x.

=back

=head2 Transcendental operations

These opcodes handle the transcendental math functions. The destination
register here must always be either a numeric or a PMC register.

=over 4

=item sin nx, ty

Return the sine of the number in Y

=item cos nx, ty

Return the cosine of the number in Y

=item tan nx, ty

Return the tangent of the number in Y

=item sec nx, ty

Return the secant of the number in Y

=item atan nx, ty

Return the arctangent of Y

=item atan2 nx, ty

Return the result of atan2 of Y

=item asin nx, ty

Return the arcsine of y

=item acos nx, ty

Return the arccosine of y

=item asec nx, ty

Return the arcsecant of y

=item cosh nx, ty

Return the hyperbolic cosine of y

=item sinh nx, ty

Return the hyperbolic sine of y

=item tanh nx, ty

Return the hyperbolic tangent of y

=item sech nx, ty

Return the hyperbolic secant of y

=item log2 nx, ty

Return the base 2 log of y

=item log10 nx, ty

Return the base 10 log of y

=item ln Nx, ty

Return the base e log of y

=item log nx, ty, tz

Return the base Z log of Y

=item pow nx, ty, tz

Return Y to the Z power

=item exp nx, ty

Return e to the Y power

=back

=head2 Register and stack ops

These opcodes deal with registers and stacks

=over 4

=item pushp

Push the current set of PMC registers onto the register frame stack, and start
a new set (which will all initially be NULL). Register frames hold only 16
registers, so we need to push two frames onto the stack. The  first frame holds
the contents of registers 0-15; the second holds the  contents of registers
16-31.

=item popp

Restore all of the PMC registers from the most recently C<push>ed PMC  register
frames. Since the register frames hold only 16 registers, we pop two frames. We
use the first frame to restore registers 16-31, and  the second frame to
restore registers 0-15. Hence, C<pushp> followed by C<popp> restores all of the
PMC registers to their original state.

=item poptopp

Pop a single PMC register frame off the PMC register frame stack and use it to
restore the values of registers 16-31. Registers 0-15 retain their old values.

=item popbottomp

Pop a single PMC register frame off the PMC register frame stack and use it to
restore the values of registers 0-15. Registers 16-31 retain their old values.

=item pushi

The same as L<pushp>, for the integer register set.

=item popi

The same as L<popp>, for the integer register set.

=item poptopi

The same as L<poptopp>, for the integer register set.

=item popbottomi

The same as L<popbottomp>, for the integer register set.

=item pushs

The same as L<pushp>, for the string register set.

=item pops

The same as L<popp>, for the string register set.

=item poptops

The same as L<poptopp>, for the string register set.

=item popbottoms

The same as L<popbottomp>, for the string register set.

=item pushn

The same as L<pushp>, for the floating-point register set.

=item popn

The same as L<popp>, for the floating-point register set.

=item poptopn

The same as L<poptopp>, for the floating-point register set.

=item popbottomn

The same as L<popbottomp>, for the floating-point register set.

=item clearp

Clean out the current set of PMC registers, setting them to NULL

=item cleari

Clean out the current set of I registers, setting them to 0

=item clears

Clean out the current set of S registers, setting them to NULL

=item clearn

Clean out the current set of N registers, setting them to 0

=item null tx

Set register X to a null value; for S and P registers, this will be NULL, while
for I and N registers it is 0

=item save tx

Push register or constant X onto the generic stack

=item restore tx

Restore register X from the generic stack by popping off the topmost entry. The
type of this entry must match the register type.

=item saveall

Save all of the current set of registers onto the appropriate frame  stacks.
Equivalent to performing a separate push for each register type.

=item restoreall

Restore all of the registers from the appropriate frame stacks. Equivalent  to
performing a separate pop for each register type.

=item savetop

As L<saveall> but only acts on registers 16-31.

=item restoretop

As L<restoreall> but only affects registers 16-31.

=item set_warp string

Sets a named marker for the stacks for later use.

=item entrytype Ix, iy

Put the type of generic stack entry Y into integer register X

=item depth Ix

Get the current depth of the generic stack

=item lookback tx, iy

Fetch the entry that's at position Y from the top of the generic stack. This
does not remove an entry from the stack, merely fetches the entry off it.

0 is the entry at the top of the stack, 1 is the entry immediately previous to
that, and so on. Entry -1 is the very bottom-most entry in the stack. (While
the stack may be a tree when looked at from the bottom up,  you don't have
access to any other branches when looking this way).

=item warp [string]

Reset the current register stacks to the state they were in when the warp was
set. Resets only the frame pointers, doesn't guarantee the contents of the
registers. Be I<very> careful modifying the frame pointers by, for example,
pushing register frames.

If a name is passed, warp back to the named point.

=item unwarp

Reset the current register stacks to the state they were in before the last
warp.

=back

=head2 Names, pads, and globals

These operations are responsible for finding names in lexical or global scopes,
as well as storing data into those slots.  A static scope is captured by a
scratchpad.  The current dynamic scope is represented by the state of the
lexical stack (which contains scratchpads).  For more detail on these ops see
the inline POD documentation in F<ops/var.ops>.

=over 4

=item new_pad ix

=item new_pad Px, iy

=item push_pad Px

=item pop_pad

=item pop_pad Px

=item peek_pad Px

Instructions for creating scratchpads and manipulating the lexical stack.

=item store_lex sx, Py

=item store_lex ix, sy, Pz

=item store_lex ix, iy, Pz

=item find_lex Px, sy

=item find_lex Px, iy, sz

=item find_lex Px, iy, iz

Instructions for storing in, and retrieving from the scratchpad currently at
the top of the lexical stack.  For each of these operations there is an
equivalent form that uses keyed versions of the set instruction. The keyed
variants require that a scratchpad be specified rather than implicitly
operating on the scratchpad on the top of the stack.

=item find_global Px, sy, sz

Find the PMC for the global variable sy from the table sz and store it in
register X

=item find_global Px, sy

Find the PMC for the global in the default table and put it in X.

=item find_global_table Px, sy

Find the global symbol table Y and store its PMC in X

=item find_global_slot ix, Py, sz

Find the slot in the global table Y for the global named Z, and store its slot
in register X.

=item fetch_global Px, Py, iz

Fetch the global in slot Z of the symbol table pointed to by Y

=item store_global Px, sy

Store X in the default global symbol table with a name of Y.

=back

=head2 Exceptions

These opcodes deal with exception handling at the lowest level. Exception
handlers are dynamically scoped, and any exception handler set in a scope will
be removed when that scope is exited.

=over 4

=item set_eh Px

Sets an exception handler in place. The code referred to by register Px will
get called if an exception is thrown while the exception handler is in scope.

=item clear_eh

Clear out the most recently placed exception

=item throw Px

Throw an exception represented by the object in PMC register x.

=item rethrow Px

Only valid inside an exception handler. Rethrow the exception represented by
the object in PMC register x. This object may have been altered by the
exception handler.

=back

=head2 Object things

These opcodes deal with PMCs as objects, rather than as opaque data items.

=over 4

=item make_object Px, ty

Make the variable in PMC x an object of type ty. The type can be a string, in
which case we treat it as a package name.

=item find_method Px, Py, tz

Find the method Z for object Y, and return a PMC for it in X.

=item call_method Px, ty

=item find_attribute Px, sy

=item set_attribute Px, ty, tz

=item can Ix, Py, sz

Sets X to TRUE if object Y can perform method Z; otherwise, X is set to FALSE.

=item does Ix, Py, sz

Sets X to TRUE if object Y can implements interface Z; otherwise, X is  set to
FALSE.

=item isa Px, ty

=back

=head2 Module handling

These opcodes deal with loading in bytecode or executable code libraries, and
fetching info about those libraries. This is all dealing with precompiled
bytecode or shared libraries.

=over 4

=item load_bytecode sx

Load in the bytecode in file X. Search the library path if need be.

=item load_opcode_lib sx, iy

Load in the opcode library X, starting at opcode number Y. Search the path if
needed.

=item load_string_lib sx

Load in the string handling library named X

=item get_op_count sx

Return the number of opcodes in opcode library X

=item get_string_name sx

Get the name of the string encoding that the library X handles

=item find_string_lib sx, sy

Find the string library that handles strings of type Y. Return its name in X.

=back

=head2 I/O operations

Reads and writes read and write records, for some value of record.

=over 4

=item new_fh px

Create a new filehandle px

=item open px, sy

Open the file Y on filehandle X

=item read px, py, pz

Issue a read on the filehandle in y, and put the result in PMC X. PMC Z is the
sync object.

=item write px, sy, pz

Write the string Y to filehandle X. PMC Z is the sync object.

=item wait px

Wait for the I/O operation represented by sync object X to finish

=item readw px, py

Read from filehandle Y and put the results in PMC X. Blocks until the read
completes.

=item writew px, sy

Write string Y to filehandle X, waiting for the write to complete.

=item seek px, ty

Seek filehandle X to position Y.

=item tell tx, py

Return the current position of filehandle Y and put it in X. Returns -1 for
filehandles where this can't be determined. (Such as stream connections)

=item status px, py, tz

Get informational item Z for filehandle Y and put the result in X. This fetches
things like the number of entries in the IO pipe, number of outstanding I/O
ops, number of ops on the filehandle, and so forth.

=back

=head2 Threading ops

=over 4

=item lock Px

Take out a high-level lock on the PMC in register X

=item unlock Px

Unlock the PMC in register X

=item pushunlock Px

Push an unlock request on the stack

=back

=head2 Interpreter ops

=over 4

=item newinterp Px, flags

Create a new interpreter in X, using the passed flags.

=item runinterp Px, iy

Jump into interpreter X and run the code starting at offset Y from the current
location. (This is temporary until we get something better)

=item callout Pw, Px, sy, pz

Call routine Y in interpreter x, passing it the list of parameters Z. W is a
synchronization object returned. It can be waited on like the sync objects
returned from async I/O routines.

=item interpinfo Ix, iy

Get information item Y and put it in register X. Currently defined are:

=over 4

=item 1 TOTAL_MEM_ALLOC

The total amount of system memory allocated for later parceling out to Buffers.
Doesn't include any housekeeping memory, memory for Buffer or PMC structs, or
things of that nature.

=item 2 DOD_RUNS

The total number of dead object detection runs that have been made.

=item 3 COLLECT_RUNS

The total number of memory collection runs that have been made.

=item 4 ACTIVE_PMCS

The number of PMCs considered active. This means the DOD scan hasn't noted them
as dead.

=item 5 ACTIVE_BUFFERS

The number of Buffers (usually STRINGs but could be other things) considered
active.

=item 6 TOTAL_PMCS

The total number of PMCs the interpreter has available. Includes both active
and free PMCs

=item 7 TOTAL_BUFFERS

The total number of Buffer structs the interpreter has available.

=item 8 HEADERS_ALLOC_SINCE_COLLECT

The number of new Buffer header block allocations that have been made since the
last DOD run. (Buffers, when allocated, are allocated in chunks)

=item 9 MEM_ALLOCS_SINCE_COLLECT

The number of times we've requested a block of memory from the system for
allocation to Buffers since the last time we compacted the memory heap.

=back

=back

=head2 Garbage collection

=over 4

=item sweep

Fire off a dead object sweep

=item collect

Fire off a garbage collection sweep

=item pausecollect

Pause the garbage collector. No collections will be done for this interpreter
until the collector is unpaused.

=item resumecollect

Unpause the collector. This doesn't necessarily do a GC run, merely allows the
interpreter to fire one off when it deems it necessary.

=back

=head2 Key operations

Keys are used to get access to individual elements of an aggregate variable. 
This is done to allow for opaque, packed, and multidimensional aggregate types.

A key entry may be an integer, string, or PMC. Integers are used for array
lookups, strings for hash lookups, and PMCs for either.

=over 4

=item new_key Sx

Create a new key structure and put a pointer to it in register X.

=item clone_key Sx, ky

Make a copy of the key Y and put a pointer to it in register X. Y may be either
an S register or a constant.

=item size_key Sx, iy

Make the key structure X large enough to hold Y key entries

=item key_size Ix, ky

Put the number of elements in key Y into integer register X.

=item toss_key Sx

Nuke key X. Throws the structure away and invalidates the register.

=item ke_type Ix, ky, iz

Put the type of key Y's entry Z in register X. Current values are 0, 1, and 2
for Integer, String, and PMC, respectively.

=item ke_value tx, ky, iz

Put the value from key Y, entry Z into register X.

=item chop_key Sx

Toss the topmost entry from key X.

=item inc_key Sx, iy

Increment entry Y of key X by one.

=item set_key Sw, [isp]x, iy[, iz]

Set key W, offset Y, to value X. If X is a PMC, then the fourth operand must be
specified. It can have a value of 0, 1, or 2, corresponding to integer, string,
or object. Aggregates use this to figure out how to treat the key entry.

=back

=head2 Properties

Properties are a sort of runtime note attached to a PMC. Any PMC can have
properties on it. Properties live in a flat namespace, and they are not in any
way associated with the class of the PMC that they are attached to.

Properties may be used for runtime notes on variables, or other metadata that
may change. They are not for object attributes.

=over 4

=item setprop Px, sy, Pz

Set the property named Y of PMC X to the PMC in Z

=item getprop Px, sy, Pz

Get the property named Y from PMC Z and put the result in register X. Returns a
NULL if the property doesn't exist.

=item delprop Px, sy

Delete the property Y from PMC X

=item prophash Px, Py

Fetch the properties from Y, put them in a Hash, and put the Hash in X.

=back

=head2 Symbolic support for HLLs

=over 4

=item setline ix

Sets the 'current line' marker.

=item setfile sx

Sets the 'current file' marker.

=item setpackage sx

Sets the 'current package' marker.

=item getline ix

Fetches the 'current line' marker.

=item getfile sx

Fetches the 'current file' marker.

=item getpackage sx

Fetches the 'current package' marker.

=back

=head2 Foreign library access

These are the ops we use to load in and interface to non-parrot libraries.

=over 4

=item loadlib Px, Sy

Load in the library whose name is specified by y, and put a handle to it into P
register x.

=item dlfunc Pw, Px, Sy, Sz

Find a routine named Y, in library X (which you did, of course, open with
loadlib), and put a sub PMC onto W for it. You can call this sub as if it were
any other parrot subroutine.

Z has the function signature, which tells Parrot how to build the interface
from parrot (and parrot's calling conventions) to the calling conventions of
the library routine. Yes, this does mean that you must know the function
signature, but if you don't know that why the heck would you be invoking the
function, right?

The signature is a series of 1 or more characters, representing the types for
the call. The first character is the return type, while the rest are the
parameters. The types are:

=over 4

=item v

Void. As a return type indicates that there I<is> no return type. As a
parameter indicates that there are no parameters. Can't be mixed with other
parameter types.

=item c

Char. This is an integer type, taken from (or put into) an I register.

=item s

short. An integer type, taken from 0 or put into an I register

=item i

int. An integer type.

=item l

long. An integer type. You know the drill.

=item f

float. F register denizen.

=item d

double. F register, double-precision floating point type

=item p

PMC thingie. A generic pointer, taken from or stuck into a PMC's data pointer.
If this is a return type, parrot will create a new UnManagedStruct PMC type,
which is just a generic "pointer so some damn thing or other" PMC type which
Parrot does I<no> management of.

=item t

string pointer. Taken from, or stuck into, a string register. (Converted to a
null-terminated C string before passing in)

=back

So the signature for, for example, this SDL routine:

   int SDL_BlitSurface(SDL_Surface *src,
                       SDL_Rect    *srcrect,
                       SDL_Surface *dst,
                       SDL_Rect    *dstrect);

would be C<ipppp>, since it returns an integer and takes four pointers.
Presumably previous calls would have set those pointers up properly.

Do note that parrot makes no guarantees as to the behaviour of the libraries,
and currently does no type checking on the input parameters. We will fix that
later.

The generated routine follows the calling conventions in PDD03. Note that int,
string, pmc, and float parameters are counted separately. So if you have a
signature of C<ippiidd> the return goes into I5, and the parameters come from
P5, P6, I5, I6, N5, and N6, respectively. A signature of C<ipdiidp> has the
identical same set of registers used (and in the same order).

=item invoke

Invoke a subroutine in P0. Presumes that all the registers are set up right for
the call. The invoked subroutine I<must> preserve any registers that are not
explicitly return parameters or calling convention metadata parameters. (Such
as the number of I reg parameters, for example)

=back

=head2 Runtime compilation

These opcodes deal with runtime creation of bytecode and compilation of source
code.

=over 4

=item compile Px, Py, Sz

Compile source string Z, with compiler unit Y, and stick a handle to a
subroutine for the resulting bytecode segment (already loaded into the current
interpreter) into X.

Y is a assembler/compiler object of some sort, as registered with the
B<compreg> opcode or the Parrot_compreg function. This will be something like
"Perl5", "Perl6", "Perl5RE", "Perl6RE", "Python", "Ruby"... you get the
picture.

Parrot knows of a "PASM1" compiler, i.e. a one statement PASM compiler
implemented as PDB_eval. Imcc registers "PASM" and "PIR" compilers.

This is a high-level op, with the assumption that the resulting sub will be
called. It's the equivalent of perl 5's string eval, except for the actual
execution of the resulting code.

=item compreg Px, Sy

Get a compiler for source type Y.

=item compreg Sx, Py

Register the sub Y as a parser/compiler function named X. It will be called
whenever anyone invokes the compile op with the name X.

=back

=head1 ATTACHMENTS

None.

=head1 REFERENCES

None.

=head1 VERSION

None.

=head2 CURRENT

    Maintainer: Dan Sugalski
    Class: Internals
    PDD Number: 6
    Version: 1.8
    Status: Developing
    Last Modified: 02 December 2002
    PDD Format: 1
    Language: English

=head2 HISTORY

=over 4

=item Version 1.8

December 11, 2002

=item Version 1.7

December 02, 2002

=item Version 1.6

November 05, 2001

=item Version 1.5

October 12, 2001

=item Version 1.4

September 24, 2001

=item Version 1.3

September 12, 2001

=item Version 1.2

August 25, 2001

=item Version 1.1

August 8, 2001

=item version 1

None. First version

=back

=head1 CHANGES

=over 4

=item Version 1.8

=over 4

=item * Added property ops

=item * Fixed some bad register designations

=item * Opened up opcode name character list to include numbers

=back

=item Version 1.7

=over 4

=item * Fixed stack ops

push, pop, and clear properly documented according to the engine's behaviour
now.

=back

=item Version 1.6

=over 4

=item * Added GC opcodes

=back

=item Version 1.5

=over 4

=item * Now have a bsr in addition to a jsr

=item * return is now ret

=item * Added save and restore ops for saving and restoring individual registers

=back

=item Version 1.4

=over 4

=item * Conditional branches have just a true destination now

=item * Added the I/O ops

=item * Added in the threading ops

=item * Added in the interpreter ops

=back

=item Version 1.3

=over 4

=item * Added in the low-level module loading ops

=item * Added in transcendental functions and modulo

=item * Finished the pad/global variable fetching bits

=back

=item Version 1.2

We have an interpreter now! Yay! (Okay, a simple one, but still...) Changes
made to reflect that.

=item Version 1.1

=over 4

=item * Added in object

=item * Changed remnants of "perl" to "Parrot"

=item * Branch destination may be integer constant

=item * Added L<Assembly Syntax> section

=back

=item Version 1.0

None. First version

=back

