This is cgen.info, produced by makeinfo version 4.8 from cgen.texi.

START-INFO-DIR-ENTRY
* Cgen: (cgen).                 The Cpu tools GENerator.
END-INFO-DIR-ENTRY

   Copyright (C) 2000, 2007, 2009 Red Hat, Inc.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the entire resulting derived work is distributed under the terms
of a permission notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions.


File: cgen.info,  Node: Top,  Next: Introduction,  Up: (dir)

Introduction
************

This manual documents the CGEN program, version 1.1.50.

* Menu:

* Introduction::                Introduction
* Running CGEN::		How to run CGEN
* RTL::                         The Register Transfer Language CGEN uses
* Preprocessor macros::         Macros to simplify description file writing
* Porting::                     Porting
* Opcodes::                     Assembler/disassembler support
* Simulation::                  Simulation support
* Writing an application::      Writing your own CGEN application
* Glossary::                    Glossary
* Miscellaneous notes::         Notes needing a better home
* Credits::			Credits
* Index::                       Index


File: cgen.info,  Node: Introduction,  Next: Running CGEN,  Prev: Top,  Up: Top

1 Introduction to CGEN
**********************

* Menu:

* Overview::
* CPU description language::
* Opcodes support::
* Simulator support::
* Testing support::


File: cgen.info,  Node: Overview,  Next: CPU description language,  Up: Introduction

1.1 Overview
============

CGEN is a project to provide a framework and toolkit for writing cpu
tools.

* Menu:

* Goal::                        What CGEN tries to achieve.
* Why do it?::
* Maybe it should not be done?::
* How ambitious is CGEN?::
* What is missing that should be there someday?::


File: cgen.info,  Node: Goal,  Next: Why do it?,  Up: Overview

1.1.1 Goal
----------

The goal of CGEN (pronounced _seejen_, and short for "Cpu tools
GENerator") is to provide a uniform framework and toolkit for writing
programs like assemblers, disassemblers, and simulators without
explicitly closing any doors on future things one might wish to do.  In
the end, its scope is the things the software developer cares about
when writing software for the cpu (compilation, assembly, linking,
simulation, profiling, debugging, ???).

   Achieving the goal is centered around having an application
independent description of a CPU (plus environment, like ABI) that
applications can then make use of.  In the end that's a lot to ask for
from one language.  What applications can or should be able to use CGEN
is left to evolve over time.  The description language itself is thus
also left to evolve over time!

   Achieving the goal also involves having a toolkit, libcgen, that
contains a compiled form of the cpu description plus a suite of
routines for working with the data.  (1)

   CGEN is not a new idea.  Some GNU ports have done something like
this - for example, the SH port in its early days.  However, the idea
never really "caught on".  CGEN was started because I think it should.

   Since CGEN is a very ambitious project, there are currently lots of
things that aren't written down, let alone implemented.  It will take
some time to flush all the details out, but in and of itself that
doesn't necessarily mean they can't be flushed out, or that they
haven't been considered.

   ---------- Footnotes ----------

   (1) `libcgen' currently doesn't exist, but that was the original
plan.


File: cgen.info,  Node: Why do it?,  Next: Maybe it should not be done?,  Prev: Goal,  Up: Overview

1.1.2 Why do it?
----------------

I think it is important that GNU assembler/disassembler/simulator ports
be done from a common framework.  On some level it's fun doing things
from scratch, which was and still is to a large extent current
practice, but this is not the place for that.

   * the more ports of something one has, the more important it is that
     they be the same.

   * the more complex each of them become, the more important it is
     that they be the same.

   * if they all are the same, a feature added to one is added to all
     of them-within the context of their similarity, of course.

   * with a common framework in place the planning of how to architect
     a port is taken care of, the main part of what's left is simply
     writing the CPU description.

   * the more applications that use the common framework, the fewer
     places the data needs to be typed in and maintained.

   * new applications can take advantage of data and utilities that
     already exist.

   * a common framework provides a better launching point for bigger
     things.


File: cgen.info,  Node: Maybe it should not be done?,  Next: How ambitious is CGEN?,  Prev: Why do it?,  Up: Overview

1.1.3 Maybe it should not be done?
----------------------------------

However, no one has yet succeeded in pushing for such an extensive
common framework.(1)

   * maybe people think it's not worth it?

   * maybe they just haven't had the inclination to see it through?
     (where "inclination" includes everything from the time it would
     take to the dealing with the various parties whose turf you would
     tread on)

   * maybe in the case of assemblers and simulators they're not complex
     enough to see much benefit?

   * maybe the resulting tight coupling among the various applications
     will cause problems that offset any gains?

   * maybe there's too much variance to try to achieve a common
     framework, so that all attempts are doomed to become overly
     complex?

   * as a corollary of the previous item, maybe in the end trying to
     combine ISA syntax (the assembly language), with ISA semantics
     (simulation), with architecture implementation (performance),
     would become overly complex?

   ---------- Footnotes ----------

   (1) I'm just trying to solicit input here.  Maybe these questions
will help get that input.


File: cgen.info,  Node: How ambitious is CGEN?,  Next: What is missing that should be there someday?,  Prev: Maybe it should not be done?,  Up: Overview

1.1.4 How ambitious is CGEN?
----------------------------

CGEN is a very ambitious project, as future projects can be:

* Menu:

* More complicated simulators::
* Profiling tools::
* Program analysis tools::
* ABI description::
* Machine generated architecture reference material::
* Tools like what NJMCT provides::
* Input to a compiler backend::
* Hardware/software codesign::


File: cgen.info,  Node: More complicated simulators,  Next: Profiling tools,  Up: How ambitious is CGEN?

1.1.4.1 More complicated simulators
...................................

Current CGEN-based simulators achieve their speed by using GCC's
"computed goto" facility to implement a threaded interpreter.  The
"main loop" of the cpu engine is contained within one function and the
administrivia of running the program is reduced to about three host
instructions per target instruction (one to increment a "virtual pc",
one to fetch the address of code that implements that next target
instruction, and one to branch to it).  Target instructions can be
simulated with as few as seven(1) instructions for an "add" (load
address of src1, load src1, load address of src2, load src2, add, load
address of result, store result).  So ignoring overhead (which is
minimal for frequently executed code) that's ten host instructions per
"typical" target instruction.  Pretty good.(2)

   However, things can still be better.  There is still some
implementation related overhead that can be removed.  The two
instructions to branch to the next instruction would be unnecessary if
instruction executors were concatenated together.  The fetching and
storing of target registers can be reduced if target registers were
kept in host registers across instruction boundaries (and the longer
one can keep them in host registers the better).  A consequence of both
of these improvements is the number of memory operations is drastically
reduced.  There isn't a lot of ILP in the simulation of target
instructions to hide memory latencies.  Another consequence of these
improvements is the opportunity to perform inter-target-instruction
scheduling of the host instructions and other optimizations.

   There are two ways to achieve these improvements.  Both involve
converting basic blocks (or superblocks) in the target application into
the host instruction set and compiling that.  The first way involves
doing this "offline".  The target program is analyzed and each
instruction is converted into, for example, C code that implements the
instruction.  The result is compiled and then the new version of the
target program is run.

   The second way is to do the translation from target instruction set
to host instruction set while the target program is running.  This is
often referred to as JIT (Just In Time) simulation (FIXME: proper
phrasing here?).  One way to implement this is to simulate instructions
the way existing CGEN simulators do, but keep track of how frequently a
basic block is executed.  If a block gets executed often enough, then
compile a translation of it to the host instruction set and switch to
using that.  This avoids the overhead of doing the compilation on code
that is rarely executed.  Note that here is one place where a dual cpu
system can be put to good use.  One cpu handles the simulation and the
other handles compilation (translating target instructions to host
instructions).  CGEN can(3) handle a large part of building the JIT
compiler because both host and target architectures are recorded in a
way that is amenable to program manipulation.

   A hybrid of these two ways is to translate target basic blocks to C
code, compile it, and dynamically load the result into the running
simulation.  Problems with this are that one must invoke an external
program (though one could dynamically load a special form of C compiler
I suppose) and there's a lot of overhead parsing and optimizing the C
code.  On the other hand one gets to take full advantage of the
compiler's optimization technology.  And if the application takes a
long time to simulate, the extra cost may be worthwhile.  A dual cpu
system is of benefit here too.

   ---------- Footnotes ----------

   (1) Actually, this can be reduced even more by creating copies of an
instruction specialized for all the various inputs.

   (2) The actual results depend, of course, on the exact mix of target
instructions in the application, what instructions the host cpu has,
and how efficiently the rest of the simulator is (e.g. floating point
and memory operations can require a hundred or more host instructions).

   (3) This hasn't actually been implemented so there is some hand
waving here.


File: cgen.info,  Node: Profiling tools,  Next: Program analysis tools,  Prev: More complicated simulators,  Up: How ambitious is CGEN?

1.1.4.2 Profiling tools
.......................

It is useful to know how well an architecture is being utilized.  For
one, this helps build better architectures.  It also helps determine
how well a compilation system is using an architecture.

   CGEN-based simulators already compute instruction frequency counts.
It's straightforward to add register frequency counts.  Monitoring
other aspects of the ISA is also possible.  The description file
provides all the necessary data, all that's needed is to write a
generator for an application that then performs the desired analysis.

   Function unit, pipeline, and other architecture implementation
related items requires a lot more effort but it is doable.  The
guideline for this effort is again coming up with an
application-independent specification of these things.

   CGEN does not currently support memory or cache profiling.
Obviously they're important, and support may be added in the future.
One thing that would be straightforward to add is the building of trace
data for usage by cache and memory analysis tools.  The point though is
that these tools won't benefit much from CGEN's existence.

   Another kind of profiling tool is one that takes the program to be
profiled as input, inserts profiling code into it, and then generates a
new version of the program which is then run.(1) Recorded in CGEN's
description files should be all the necessary ISA related data to do
this.  One thing that's missing is code to handle the file format and
relocations.*Note ABI description::.

   ---------- Footnotes ----------

   (1) Note that there are other uses for such a program modification
tool besides profiling.


File: cgen.info,  Node: Program analysis tools,  Next: ABI description,  Prev: Profiling tools,  Up: How ambitious is CGEN?

1.1.4.3 Program analysis tools
..............................

Related to profiling tools are static program analysis tools.  By this
I mean taking machine code as input and analyzing it in some way.
Except for symbolic information (which could come from BFD or
elsewhere), CGEN provides enough information to analyze machine code,
both the raw instructions *and* their semantics.  Libcgen should contain
all the basic tools for doing this.  (1)

   ---------- Footnotes ----------

   (1) Today this is libopcodes to some degree.


File: cgen.info,  Node: ABI description,  Next: Machine generated architecture reference material,  Prev: Program analysis tools,  Up: How ambitious is CGEN?

1.1.4.4 ABI description
.......................

Several tools need knowledge of not only a cpu's ISA but also of the ABI
in use.  I think(!) it makes sense to apply the same goals that went
into CGEN's architecture description language to an ABI description
language: specify the ABI in an application independent way and then
have a basic toolkit/library that provides ways of using that data.  It
might be useful to also allow the writing of program generators for
applications that want more than what the toolkit/library provides.
Perhaps not, but the basic toolkit/library should, again I think, be
useful.

   Part of what an ABI defines is the file format and relocations.
This is something that BFD is built for.  I think a BFD rewrite should
happen and should be based, at least in part, on a CGEN-style ABI
description.  This rewrite would be one user of the ABI description,
but certainly not the only user.  One problem with this approach is
that BFD requires a lot of file format specific C code.  I doubt all of
this code is amenable to being described in an application independent
way.  Careful separation of such things will be necessary.  It may even
be useful to ignore old file formats and limit such a BFD rewrite to
ELF (not that ELF is free from such warts, of course).


File: cgen.info,  Node: Machine generated architecture reference material,  Next: Tools like what NJMCT provides,  Prev: ABI description,  Up: How ambitious is CGEN?

1.1.4.5 Machine generated architecture reference material
.........................................................

Engineers often need to refer to architecture documentation.  One
problem is that there's often only so many hardcopy manuals to go
around.  Since the CPU description contains a lot of the information
engineers need to find it makes sense to convert that information back
into a readable form.  The manual can then be online available to
everyone.  Furthermore, each architecture will be documented using the
same style making it easier to move from architecture to architecture.


File: cgen.info,  Node: Tools like what NJMCT provides,  Next: Input to a compiler backend,  Prev: Machine generated architecture reference material,  Up: How ambitious is CGEN?

1.1.4.6 Tools like what NJMCT provides
......................................

NJMCT is the New Jersey Machine Code Toolkit.  It focuses exclusively
on the encoding and decoding of instructions.  [FIXME: wip, need to say
more].


File: cgen.info,  Node: Input to a compiler backend,  Next: Hardware/software codesign,  Prev: Tools like what NJMCT provides,  Up: How ambitious is CGEN?

1.1.4.7 Input to a compiler backend
...................................

One can define a GCC port to include these four things:

   * cpu architecture description

   * cpu implementation description

   * ABI description

   * miscellaneous

   The CGEN description provides all of the cpu architecture description
that the compiler needs.  However, the current design of the CPU
description language is geared towards going from machine instructions
to semantic content, whereas what a compiler wants is to do is go from
semantic content to machine instructions, so in the end this might not
be a reasonable thing to pursue.  On the other hand, that problem can
be solved in part by specifying two sets of semantics for each
instruction: one for the compiler side of things, and one for the
simulator side of things.  Frequently they will be the same thing and
thus need only be specified once.  Though specifying them twice, for
the two different contexts, is reasonable I think.  If the two versions
of the semantics are used by multiple applications this makes even more
sense.

   The planned rewrite of model support in CGEN will support whatever
the compiler needs for the implementation description.

   Compilers also need to know the target's ABI, which isn't relevant
for an architecture description.  On the other hand, more than just the
compiler needs knowledge of the ABI.  Thus it makes sense to think about
how many tools there are that need this knowledge and whether one can
come up with a unifying description of the ABI.  Hence one future
project is to add the ABI description to CGEN.  This would encompass in
essence most of what is contained in the System V ABI documentation.

   That leaves the "miscellaneous" part.  Essentially this is a catchall
for whatever else is needed.  This would include things like include
file directory locations, port-specific language features, ???.
There's not much need to include this info in CGEN, it's pretty
esoteric and generally useful to only a few applications.

   One can even envision a day when GCC emits object files directly.
The instruction description contains enough information to build the
instructions and the ABI support would provide enough information on
relocations and object file formats.

   Debugging information should be treated as an orthogonal concept.
At present it is outside the scope of CGEN, though clearly the same
reasoning behind CGEN applies to debugging support as well.


File: cgen.info,  Node: Hardware/software codesign,  Prev: Input to a compiler backend,  Up: How ambitious is CGEN?

1.1.4.8 Hardware/software codesign
..................................

This section isn't very well thought out - not much time has been put
into it.  The thought is that some interface with VHDL/Verilog could be
created that would assist hw/sw codesign.

   Another related application is to have a feedback mechanism from the
compilation system that helps improve the architecture description
(both CGEN and HDL).  CGEN descriptions for experimental instructions
could be added, and a new set of compilation tools quickly regenerated.
Then experiments could be run analyzing the effectiveness of the new
instructions.


File: cgen.info,  Node: What is missing that should be there someday?,  Prev: How ambitious is CGEN?,  Up: Overview

1.1.5 What's missing that should be there someday?
--------------------------------------------------

   * Support for complex ISA's (i386, m68k).

     Early versions had the framework of the support, but it's all
     bit-rotten.

   * ABI description

     As discussed elsewhere, one thing that many tools need knowledge
     of besides the ISA is the ABI.  Clearly ABI's are orthogonal to
     ISA's and one cpu may have multiple ABI's running on it.  Thus the
     ABI description needs to be independent of the architecture
     description.  It would still be useful for the ABI to refer to
     things in the architecture description.

   * Model description

     The current design is enough to get reasonable cycle counts from
     the simulator but it doesn't take into account all the uses one
     would want to make of this data.

   * File organization

     I believe a lot of what is in libopcodes should be moved to
     libcgen.  Libcgen will contain the bulk of the cpu description in
     processed form.  It will also contain a suite of utilities for
     accessing the data.

     ABI support could either live in libcgen or separately in
     libcgenabi.  libbfd would be a user of this library.

     Instruction semantics should also be recorded in libcgen, probably
     in bytecode form.  Operand usage tables, needed for example by the
     m32r assembler, could be lazily computed at runtime.  Operand
     usage tables are also useful to gdb's reverse-execution support.

     Applications can either make use of libcgen or given the
     application independence of the description language they can
     write their own code generators to tailor the output as needed.



File: cgen.info,  Node: CPU description language,  Next: Opcodes support,  Prev: Overview,  Up: Introduction

1.2 CPU description language
============================

The goal of CGEN is to provide a uniform and extensible framework for
doing assemblers/disassemblers and simulators, as well as allowing
further tools to be developed as necessary.

   With that in mind I think the place to start is in defining a CPU
description language that is sufficiently powerful for all the current
and perceived future needs: an application independent description of
the CPU.  From the CPU description, tables and code can be generated
that an application framework can then use (e.g. opcode table for
assembly/disassembly, decoder/executor for simulation).

   By "application independence" I mean the data is recorded in a way
that doesn't intentionally close any doors on uses of the data.  One
example of this is using RTL to describe instruction semantics rather
than, say, C.  The assembler can also make use of the instruction
semantics.  It doesn't make use of the semantics, per se, but what it
does use is the input and output operand information that is machine
generated from the semantics.  Grokking operand usage from C is
possible, but harder.  (1) So by writing the semantics in RTL multiple
applications can make use of it.  One can also generate from the RTL
code in languages other than C.

* Menu:

* Language requirements::
* Layout::
* Language problems::

   ---------- Footnotes ----------

   (1) By this I mean analyzing the C and understanding what it's doing.


File: cgen.info,  Node: Language requirements,  Next: Layout,  Up: CPU description language

1.2.1 Language requirements
---------------------------

The CPU description file needs to provide at least the following:

   * elements of the CPU's architecture (registers, etc.)

   * elements of a CPU's implementation (e.g. pipeline)

   * how the bits of an instruction word map to the instruction's
     semantics

   * semantic specification in a way that is amenable to being
     understood and manipulated

   * performance measurement parameters

   * support for multiple architecture and implementation variants

   * assembler syntax of the instruction set

   * how that syntax maps to the bits of the instruction word, and back

   * support for generating test files

   * ???

   In addition to this, elements of the particular ABI in use is also
needed.  These things will obviously need to be defined separately from
the cpu for obvious reasons.

   * file format

   * relocations

   * function calling conventions

   * structure layout

   * ... and all the other usual stuff

   Some architectures require knowledge of the pipeline in order to do
accurate simulation (because, for example, some registers don't have
interlocks) so that will be required as well, as opposed to being solely
for performance measurement.  Pipeline knowledge is also needed in order
to achieve accurate profiling information.  However, I haven't spent
much time on this yet.  The current design/implementation is a first
pass in order to get something reasonable, and will be revisited as
necessary.

   Support for generating test files is not complete.  Currently the GAS
test suite generator gets by (barely) without them.  The simulator test
suite generator just generates templates and leaves the programmer to
fill in the details.  But I think this information should be present,
meaning that for situations where test vectors can't be derived from the
existing specs, new specs should be added as part of the description
language.  This would make writing testcases an integral part of writing
the .cpu file.  Clearly there is a risk in having machine generated
testcases - but there are ways to eliminate or control the risk.

   The syntax of a suitable description language needs to have these
properties:

   * simple

   * expressive

   * easily parsed

   * easy to learn

   * understandable by program generators

   * extensible

   It would also help to not start over completely from scratch.  GCC's
RTL satisfies all these goals, and is used as the basis for the
description language used by CGEN.

   Extensibility is achieved by specifying everything as name/value
pairs.  This allows new elements to be added and even CPU specific
elements to be added without complicating the language or requiring a
new element in a `define_insn'-like entry to be added to each existing
port.  Macros can be used to eliminate the verbosity of repetitively
specifying the "name" part, so one can have it both ways.  Imagine GCC's
`.md' file elements specified as name/value pairs with macro's called
`define_expand', `define_insn', etc.  that handle the common cases and
expand the entry to the full `(define_full_expand (name addsi3)
(template ...) (condition ...) ...)'.

   Scheme also uses `(foo :keyword1 value1 :keyword2 value2 ...)',
though that isn't implemented yet (or maybe `#:keyword' depending upon
what is enabled in Guile).


File: cgen.info,  Node: Layout,  Next: Language problems,  Prev: Language requirements,  Up: CPU description language

1.2.2 Layout
------------

Here is a graphical layout of the hierarchy of elements of a `.cpu'
file.

                                architecture
                                /          \
                           cpu-family1   cpu-family2  ...
                           /         \
                       machine1    machine2  ...
                        /   \
                   model1  model2  ...

   Each of these elements is explained in more detail in *Note RTL::.
The _architecture_ is one of `sparc', `m32r', etc.  Within the `sparc'
architecture, the _cpu-family_ might be `sparc32' or `sparc64'.  Within
the `sparc32' CPU family, the _machine_ might be `sparc-v8',
`sparclite', etc.  Within the `sparc-v8' machine classificiation, the
_model_ might be `hypersparc' or `supersparc'.

   Instructions form their own hierarchy as each instruction may be
supported by more than one machine.  Also, some architectures can
handle more than one instruction set on one chip (e.g. ARM).

                          isa
                           |
                       instruction
                         /   \
                  operand1  operand2  ...
                     |         |
              hw1+ifield1   hw2+ifield2  ...

   Each of these elements is explained in more detail in *Note RTL::.


File: cgen.info,  Node: Language problems,  Prev: Layout,  Up: CPU description language

1.2.3 Language problems
-----------------------

There are at least two potential problem areas in the language's design.

   The first problem is variation in assembly language syntax.
Examples of this are Intel vs AT&T i386 syntax, and Motorola vs MIT
m68k syntax.  I think there isn't a sufficient number of important
cases to warrant handling this efficiently.  One could either ignore
the issue for situations where divergence is sufficient to dissuade one
from handling it in the existing design, or one could provide a front
end or use/extend the existing macro mechanism.

   One can certainly argue that description of assembler syntax should
be separated from the hardware description.  Doing so would prevent
complications in supporting multiple or even difficult assembler
syntaxes from complicating the hardware description.  On the other hand,
there is a lot of duplication, and in the end for the intended uses of
CGEN I think the benefits of combining assembler support with hardware
description outweigh the disadvantages.  Note that the assembler
portions of the description aren't used by the simulator (1), so if one
wanted to implement the disassembler/assembler via other means one can.

   The second problem area is relocations.  Clearly part of processing
assembly code is dealing with the relocations involved (e.g. GOT table
specification).  Relocation support necessarily requires BFD and GAS
support, both of which need cleanup in this area.  Rewriting BFD to
provide a better interface so reloc handling in GAS can be cleaned up
is believed to be something this project can and should take advantage
of, and that any attempt at adding relocation support should be done by
first cleaning up GAS/BFD.  That can be left for another day though. :-)

   One can certainly argue trying to combine an ABI description with a
hardware description is problematic as there can be more than one ABI.
However, there often isn't and in the cases where there isn't the
simplified porting and maintenance is worth it, in the author's opinion.
Furthermore, the current language doesn't embed ABI elements with
hardware description elements.  Careful segregation of such things
might ameliorate any problems.

   ---------- Footnotes ----------

   (1) The simulator currently uses elements of the opcode table since
the opcode table is a nice central repository for such things.
However, the assembler/disassembler isn't part of the simulator, and the
portions of the opcode table can be generated and recorded elsewhere
should it prove reasonable to do so.  The CPU description file won't
change, which is the important thing.


File: cgen.info,  Node: Opcodes support,  Next: Simulator support,  Prev: CPU description language,  Up: Introduction

1.3 Opcodes support
===================

Opcodes support comes in the form of machine generated opcode tables as
well as supporting routines.


File: cgen.info,  Node: Simulator support,  Next: Testing support,  Prev: Opcodes support,  Up: Introduction

1.4 Simulator support
=====================

Simulator support comes in the form of machine generated the
decoder/executer as well as the structure that records CPU state
information (i.e., registers).

   CGEN comes with support for both the simulator in the GDB tree
(*note GDB Simulator::), and the SID simulator (*note SID Simulator::).


File: cgen.info,  Node: Testing support,  Prev: Simulator support,  Up: Introduction

1.5 Testing support
===================

* Menu:

* Assembler/disassembler testing::
* Simulator testing::

   Inherent in the design is the ability to machine generate test cases
both for the assembler/disassembler and for the simulator.
Furthermore, it is not unreasonable to add to the description file data
specifically intended to assist or guide the testing process.  What
kinds of additions that will be needed is unknown at present.


File: cgen.info,  Node: Assembler/disassembler testing,  Next: Simulator testing,  Up: Testing support

1.5.1 Assembler/disassembler testing
------------------------------------

The description of instructions and their fields contains to some extent
not only the syntax but the possible values for each field.  For
example, in the specification of an immediate field, it is known what
the allowable range of values is.  Thus it is possible to machine
generate test cases for such instructions.  Obviously one wouldn't want
to test for each number that a number field can contain, however one can
generate a representative set of any size.  Likewise with register
fields, mnemonic fields, etc.  A good starting point would be the edge
cases, the values at either end of the range of allowable values.

   When I first raised the possibility of machine generated test cases
the first response I got was that this wouldn't be useful because the
same data was being used to generate both the program and the test
cases.  An error might be propagated to both and thus nullify the test.
For example if an opcode field was supposed to have the value 1 and the
description file had the value 2, then this error wouldn't be caught.
However, this assumes test cases are always generated during the
testing run!  And it ignores the profound amount of typing that is
saved by machine generating test cases!  (I discount the argument that
this kind of exhaustive testing is unnecessary).

   One solution to the above problem is to not generate the test cases
during the testing run (which was implicit in the proposal, but perhaps
should have been explicit).  Another solution is to generate the test
cases during the test run but first verify them by some external means
before actually using them in any test.  Another solution is to have
some trust in the generated tests.  Yes, some bugs may be missed, but
given the quantity of testing that can be done, some bugs may still be
caught that would otherwise have been missed.  Plus it's all
machine-driven, minimal human interaction is required.

   So how are machine generated test cases verified?  By machine, by
hand, and by time.  The test cases are checked into CVS and are not
regenerated without care.  Every time the test cases are regenerated,
the diffs are examined to ensure the bug triggering the regeneration
has been fixed and that no new bugs have been introduced.  In all
likelihood once a port is more or less done, regeneration of test cases
would stop anyway, and all further changes would be done manually.

   "By machine" means that for example in the case of ports with a
native assembler one can run the test case through the native assembler
and use that as a good first pass.

   "By hand" means one can go through each test case and verifying them
manually.  This is what is done in the case of non-machine generated
test cases, the only difference is the perceived difference in quantity.
And in the case of machine generated test cases comments can be added to
each test to help with the manual verification (e.g. a comment can be
added that splits the instruction into its fields and shows their names
and values).

   "By time" means that this process needn't be done instantaneously.
This is no different than the non-machine generated case again except in
the perceived difference in quantity of test cases.

   Note that no claim is made that manually generated test cases aren't
useful or needed.  The goal here is to enhance existing forms of
testing, not replace them.


File: cgen.info,  Node: Simulator testing,  Prev: Assembler/disassembler testing,  Up: Testing support

1.5.2 Simulator testing
-----------------------

Machine generation of simulator test cases is possible because the
semantics of each instruction is written in a way that is understandable
to the generator.  At the very least, knowledge of what the instructions
are is present!  Obviously there will be some instructions that can't
be adequately expressed in RTL and are thus not amenable to having a
test case being machine generated.  There may even be some RTL'd
semantics that fall into this category.  It is believed, however, that
there will still be a large percentage of instructions amenable to
having test cases machine generated for them.  Such test cases can
certainly be hand generated, but it is believed that this is a large
amount of unnecessary typing that typically won't be done due to the
amount.

   An example is the simple arithmetic instructions.  These take zero,
one, or more arguments and produce a result.  The description file
contains sufficient data to generate such an instruction, the hard part
is in providing the environment to set up the required inputs (e.g.
loading values into registers) and retrieve the output (e.g. retrieve a
value from a register).

   Certainly at the very least all the administrivia for each test case
can be machine generated (i.e. a template file can be generated for each
instruction, leaving the programmer to fill in the details).

   The strategies mentioned for assembler/disassembler machine-generated
test cases also apply here.


File: cgen.info,  Node: Running CGEN,  Next: RTL,  Prev: Introduction,  Up: Top

2 Running CGEN
**************

CGEN is usually run from a shell script provided by the application.
For example, in `libopcodes' there is `cgen.sh'.

   The main tasks of this script are to:

  1. Set up the arguments for cgen.

  2. Run cgen.

  3. Apply any post processing to the output files.

2.0.1 Set up the arguments for cgen.
------------------------------------

CGEN takes several standard arguments.  Each application can then add
its own arguments.  By convention generic CGEN options are lowercase
letters and applications use uppercase letters for their arguments.

* Menu:

* a::            -a Specify path of .cpu file to load.
* b::            -b Use debugging evaluator, for backtraces.
* d::            -d Start interactive debugging session.
* f::            -f Specify a set of flags to control code generation.
* h::            -h,--help Print usage information.
* i::            -i Specify isa-list entries to keep.
* m::            -m Specify mach-list entries to keep.
* s::            -s Specify the source directory.
* t::            -t Specify tracing of various things.
* v::            -v Increment the verbosity level.
* w::            -w Enable various diagnostics.
* version::      --version Print version info.

* opcodes::      Opcodes generator arguments.
* sim::          Simulator generator arguments.
* sid::          Sid generator arguments.
* html::         HTML doc generator arguments.


File: cgen.info,  Node: a,  Next: b,  Up: Running CGEN

2.1 Specify path of architecture's .cpu file to load. `-a' PATH
===============================================================

Use this option to specify the `.cpu' file to load.


File: cgen.info,  Node: b,  Next: d,  Prev: a,  Up: Running CGEN

2.2 Use debugging evaluator, for backtraces. `-b'
=================================================

Use this option when trying to debug a cgen failure.  It turns on the
debugging facilities of the underlying system, e.g. Guile, and is
typically used to produce better error messages (e.g. better
backtraces).  Guile's debugging evaluator is slower than the normal one,
so this option is off by default.


File: cgen.info,  Node: d,  Next: f,  Prev: b,  Up: Running CGEN

2.3 Start interactive debugging session. `-d'
=============================================

Use this option when trying to debug a cgen failure and you want to
enter a debugging `repl'(1) in the underlying system, e.g. Guile.

   ---------- Footnotes ----------

   (1) Read-Evaluate-Print-Loop


File: cgen.info,  Node: f,  Next: h,  Prev: d,  Up: Running CGEN

2.4 Specify a set of flags to control code generation. `-f' FLAGS
=================================================================

Use this option to pass various code generation options to the
application.  FLAGS is a space-separated list of options with the format
`name' or `name=value'.  Each application accepts its own set of
options.

* Menu:

* Opcodes Generator Options::        Opcodes Generator Options
* GDB Simulator Generator Options::  GDB Generator Simulator
* SID Simulator Generator Options::  SID Generator Simulator
* HTML Doc Generator Options::       HTML Doc Generator Options


File: cgen.info,  Node: Opcodes Generator Options,  Next: GDB Simulator Generator Options,  Up: f

2.4.1 Opcodes Generator Options
-------------------------------

The `Opcodes' generator accepts the following options:

`opinst'
     Include the operand instance table in the generated code.

`copyright=<kind>'
     The argument is the copyright to add to the generated code.  It
     must be one of `fsf' or `redhat'.

`package=<package>'
     The argument is the package the opcodes files are being generated
     for.  It must be one of `binutils', `gnusim' (the simulators in GDB
     releases) or `cygsim' (SID simulators).



File: cgen.info,  Node: GDB Simulator Generator Options,  Next: SID Simulator Generator Options,  Prev: Opcodes Generator Options,  Up: f

2.4.2 GDB Simulator Generator Options
-------------------------------------

`with-scache'
     Specify this option to enable the "semantic cache" of the
     simulator.  The simulator uses the semantic cache to speed up
     simulation by caching the decoding of instructions.

`with-profile=<fn|sw>'
     Specify this option to enable basic profiling support.

     fn - do profiling in the semantic function

     sw - do profiling in the semantic switch

`with-multiple-isa'
     Specify this option to enable multiple-isa support.  This is
     useful for the arm+thumb simulator, and allows the simulator to
     simulator programs that use both ISAs.

`with-generic-write'
     This option is for architectures that can execute multiple
     instructions in parallel.  Instruction semantics are performed by
     recording the results in a generic buffer, and doing a
     post-semantics writeback pass.

`with-parallel-only'

`copyright=<kind>'
     The argument is the copyright to add to the generated code.  It
     must be one of `fsf' or `redhat'.

`package=<package>'
     The argument is the package the simulator files are being
     generated for.  It must be one of `gnusim' (the simulators in GDB
     releases) or `cygsim' (SID simulators).



File: cgen.info,  Node: SID Simulator Generator Options,  Next: HTML Doc Generator Options,  Prev: GDB Simulator Generator Options,  Up: f

2.4.3 SID Simulator Generator Options
-------------------------------------

`with-scache'
     Specify this option to enable the "semantic cache" of the
     simulator.  The simulator uses the semantic cache to speed up
     simulation by caching the decoding of instructions.

     _NOTE:_ Not all targets support this option.

`with-pbb'
     Specify this option to enable the "pseudo basic block" engine.
     The simulator uses the pbb engine to speed up simulation by
     analyzing the instruction stream a pseudo basic block at a time.

     _NOTE:_ Not all targets support this option.

`with-sem-frags'
     Specify this option to enable the semantic fragment engine.

     _NOTE:_ This option requires `with-pbb'.

     _NOTE:_ Not all targets support this option.

`with-profile=<fn|sim>'
     Specify this option to enable basic profiling support.

     fn - do profiling in the semantic function

     sw - do profiling in the semantic switch

`with-multiple-isa'
     Specify this option to enable multiple-isa support.  This is
     useful for the arm+thumb simulator, and allows the simulator to
     simulator programs that use both ISAs.

`copyright=<kind>'
     The argument is the copyright to add to the generated code.  It
     must be one of `fsf' or `redhat'.

`package=<package>'
     The argument is the package the simulator files are being
     generated for.  It must be one of `gnusim' (the simulators in GDB
     releases) or `cygsim' (SID simulators).



File: cgen.info,  Node: HTML Doc Generator Options,  Prev: SID Simulator Generator Options,  Up: f

2.4.4 HTML Doc Generator Options
--------------------------------

`copyright=<kind>'
     The argument is the copyright to add to the generated code.  It
     must be `doc'.

`package=<package>'
     The argument is the package the opcodes files are being generated
     for.  It must be `cgen'.



File: cgen.info,  Node: h,  Next: i,  Prev: f,  Up: Running CGEN

2.5 Print usage information. `-h,--help'
========================================

The standard -help option.


File: cgen.info,  Node: i,  Next: m,  Prev: h,  Up: Running CGEN

2.6 Specify isa-list entries to keep. `-i' ISA-LIST
===================================================

Use this option select a subset of the ISAs for the architecture.  This
is useful, for example, to generate only Thumb support from an
arm+thumb description.


File: cgen.info,  Node: m,  Next: s,  Prev: i,  Up: Running CGEN

2.7 Specify mach-list entries to keep. `-m' MACH-LIST
=====================================================

Use this option to select a subset of the machines of the architecture.
This is useful, for example, to generate a simulator for a specific
variant of the architecture.


File: cgen.info,  Node: s,  Next: t,  Prev: m,  Up: Running CGEN

2.8 Specify the source directory. `-s' SRCDIR
=============================================

Use this to specify where the rest of CGEN's files are.

   For example in `Binutils' CGEN is typically a sibling of
`src/opcodes', i.e., `src/cgen'.


File: cgen.info,  Node: t,  Next: v,  Prev: s,  Up: Running CGEN

2.9 Specify tracing of various things. `-t' TRACE-LIST
======================================================

Use this to turn on the tracing of various things.  The argument is a
comma-separated list of things to trace.  At present the following may
be traced.

   * `commands'

     Trace the commands from the description file(s).

   * `pmacros'

     Trace the invocation and expansion of pmacros from the description
     file(s).

   * `all'

     Trace everything.


   Each application will invoke CGEN in its own way, so the details of
enabling tracing may vary from application to application.  Generally
though, each application has a CGENFLAGS makefile variable for passing
flags to CGEN.

   Binutils example:

     # Trace pmacro expansion while generating the m32r port's opcodes files
     # in the binutils package.
     cd obj/opcodes
     rm stamp-m32r
     make stamp-m32r CGENFLAGS="-v -b -t pmacros"


File: cgen.info,  Node: v,  Next: w,  Prev: t,  Up: Running CGEN

2.10 Increment the verbosity level. `-v'
========================================

Specifying multiple `-v' options will increase the verbosity.


File: cgen.info,  Node: w,  Next: version,  Prev: v,  Up: Running CGEN

2.11 Enable various diagnostics. `-w' DIAGNOSTIC-LIST
=====================================================

Use this to turn on warnings or errors of various things.  The argument
is a comma-separated list.  At present the following diagnostics are
supported.

   * `iformat'

     Turn on verification of the instruction format.  If an
     instruction's field list has missing bits or too many bits then a
     warning is issued.

     _NOTE:_ The checking is incomplete, but it does catch most common
     forms of errors.

   * `all'

     Turn on diagnostics for everything.


   Each application will invoke CGEN in its own way, so the details of
enabling diagnostics may vary from application to application.
Generally though, each application has a CGENFLAGS makefile variable
for passing flags to CGEN.

   Binutils example:

     # Turn on verification of instruction formats while generating
     # the m32r port's opcodes files in the binutils package.
     cd obj/opcodes
     rm stamp-m32r
     make stamp-m32r CGENFLAGS="-v -b -w iformat"


File: cgen.info,  Node: version,  Next: opcodes,  Prev: w,  Up: Running CGEN

2.12 Print version info. `--version'
====================================

The standard -version option.


File: cgen.info,  Node: opcodes,  Next: sim,  Prev: version,  Up: Running CGEN

2.13 Opcodes generator arguments
================================

The opcodes generator accepts these arguments.

``-OPC' FILE'
     Specify the path to the `.opc' file.  The `.opc' file contains C
     code that is copied to the output.  It's useful for providing
     non-standard or non-straightforward parsers and printers.

``-H' FILE'
     Generate $arch-desc.h in FILE.

``-C' `FILE''
     Generate $arch-desc.c in FILE.

``-O' FILE'
     Generate $arch-opc.h in FILE.

``-P' FILE'
     Generate $arch-opc.c in FILE.

``-Q' FILE'
     Generate $arch-opinst.c in FILE.

``-B' FILE'
     Generate $arch-ibld.h in FILE.

``-L' FILE'
     Generate $arch-ibld.in in FILE.

``-A' FILE'
     Generate $arch-asm.in in FILE.

``-D' FILE'
     Generate $arch-dis.in in FILE.



File: cgen.info,  Node: sim,  Next: sid,  Prev: opcodes,  Up: Running CGEN

2.14 Simulator generator arguments
==================================

The simulator generator accepts these arguments.

``-A' FILE'
     Generate arch.h in FILE.

``-B' FILE'
     Generate arch.c in FILE.

``-C' FILE'
     Generate cpu-<cpu>.h in FILE.

``-U' FILE'
     Generate cpu-<cpu>.c in FILE.

``-N' FILE'
     Generate cpu-all.h in FILE.

``-F' FILE'
     Generate memops.h in FILE.

``-G' FILE'
     Generate defs.h in FILE.

``-P' FILE'
     Generate semops.h in FILE.

``-T' FILE'
     Generate decode.h in FILE.

``-D' FILE'
     Generate decode.c in FILE.

``-E' FILE'
     Generate extract.c in FILE.

``-R' FILE'
     Generate read.c in FILE.

``-W' FILE'
     Generate write.c in FILE.

``-S' FILE'
     Generate semantics.c in FILE.

``-X' FILE'
     Generate sem-switch.c in FILE.

``-O' FILE'
     Generate ops.c in FILE.

``-M' FILE'
     Generate model.c in FILE.

``-L' FILE'
     Generate mainloop.in in FILE.



File: cgen.info,  Node: sid,  Next: html,  Prev: sim,  Up: Running CGEN

2.15 Sid generator arguments
============================

The SID simulator generator accepts these arguments.

``-H' FILE'
     Generate desc.h in FILE.

``-C' FILE'
     Generate cpu.h in FILE.

``-E' FILE'
     Generate defs.h in FILE.

``-T' FILE'
     Generate decode.h in FILE.

``-D' FILE'
     Generate decode.cxx in FILE.

``-W' FILE'
     Generate write.cxx in FILE.

``-S' FILE'
     Generate semantics.cxx in FILE.

``-X' FILE'
     Generate sem-switch.cxx in FILE.

``-M' FILE'
     Generate model.cxx in FILE.

``-N' FILE'
     Generate model.h in FILE.



File: cgen.info,  Node: html,  Prev: sid,  Up: Running CGEN

2.16 HTML doc generator arguments
=================================

The HTML doc generator accepts these arguments.

``-H' FILE'
     Generate $arch.html in FILE.

``-I' FILE'
     Generate $arch-insn.html in FILE.

``-N' FILE'
     Set the name of the insn.html file as FILE.



File: cgen.info,  Node: RTL,  Next: Preprocessor macros,  Prev: Running CGEN,  Up: Top

3 CGEN's Register Transfer Language
***********************************

CGEN uses a variant of GCC's Register Transfer Language as the basis for
its CPU description language.

* Menu:

* RTL Introduction::            Introduction to CGEN's RTL
* Trade-offs::                  Various trade-offs in the design
* Rules and notes::             Rules and notes common to all entries
* RTL Versions::                Supported versions and differences
* Top level conditionals::      Conditional definitions
* Definitions::                 Definitions in the description file
* Attributes::                  Random data associated with any entry
* Architecture variants::       Specifying variations of a CPU
* Model variants::              Specifying variations of a CPU's implementation
* Hardware elements::           Elements of a CPU
* Instruction fields::          Fields of an instruction
* Enumerated constants::        Assigning useful names to important numbers
* Keywords::                    Like enums, plus string table
* Instruction operands::        Operands of instructions
* Derived operands::            Operands for CISC-like architectures
* Instructions::                Instructions
* Macro-instructions::          Macro instructions
* Modes::                       Operand types in expressions
* Expressions::                 Expressions in the language
* Macro-expressions::           A simplification of arithmetic expressions


File: cgen.info,  Node: RTL Introduction,  Next: Trade-offs,  Up: RTL

3.1 RTL Introduction
====================

The description language, or RTL (1), needs to support the definition
of all the architectural and implementation features of a CPU, as well
as enough information for all intended applications.  At present this
is just the opcodes table and an ISA level simulator, but it is not
intended that applications be restricted to these two areas.  The goal
is having an application independent description of the CPU.  In the
end that's a lot to ask for from one language.  Certainly gate level
specification of a CPU is not attempted!

   The syntax of the language is inspired by GCC's RTL and by the Scheme
programming language, theoretically taking the best of both.  To what
extent that is true, and to what extent that is sufficient inspiration
is certainly open to discussion.  In actuality, there isn't much
difference here from GCC's RTL that is attributable to being
Scheme-ish.  One important Scheme-derived concept is arbitrary
precision of constants.  Sign or zero extension of constants in GCC has
always been a source of problems.  In CGEN'S RTL constants have modes
and there are both signed and unsigned modes.

   Here is a graphical layout of the hierarchy of elements of a `.cpu'
file.

                                architecture
                               /            \
                         cpu-family1        cpu-family2  ...
                           /     \            /      \
                     machine1   machine2  machine3   ...
                      /   \
                  model1  model2  ...

   Each of these elements is explained in more detail below.  The
_architecture_ is one of `sparc', `m32r', etc.  Within the `sparc'
architecture, _cpu-family_ might be `sparc32', `sparc64', etc.  Within
the `sparc32' CPU family, the _machine_ might be `sparc-v8',
`sparclite', etc.  Within the `sparc-v8' machine classification, _model_
might be `hypersparc', `supersparc', etc.

   Instructions form their own hierarchy as each instruction may be
supported by more than one machine.  Also, some architectures can
handle more than one instruction set on one chip (e.g. ARM).

                          isa
                           |
                      instruction
                         /   \
                  operand1  operand2  ...
                     |         |
              hw1+ifield1   hw2+ifield2  ...

   Each of these elements is explained in more detail below.

   ---------- Footnotes ----------

   (1) While RTL stands for Register Transfer Language, it is also used
to denote the CPU description language as a whole.


File: cgen.info,  Node: Trade-offs,  Next: Rules and notes,  Prev: RTL Introduction,  Up: RTL

3.2 Trade-offs
==============

While CGEN is written in Scheme, this is not a requirement.  The
description language should be considered absent of any particular
implementation, though certainly some things were done to simplify
reading `.cpu' files with Scheme.  Scheme related choices have been
made in areas that have no serious impact on the usefulness of the CPU
description language.  Places where that is not the case need to be
revisited, though there currently are no known ones.

   One place where the Scheme implementation influenced the design of
CGEN's RTL is in the handling of modes.  The Scheme implementation was
simplified by treating modes as an explicit argument, rather than as an
optional suffix of the operation name.  For example, compare `(add SI
dr sr)' in CGEN versus `(add:SI dr sr)' in GCC RTL.  The mode is
treated as optional so a shorthand form of `(add dr sr)' works.


File: cgen.info,  Node: Rules and notes,  Next: RTL Versions,  Prev: Trade-offs,  Up: RTL

3.3 Rules and notes
===================

A few basic guidelines for all entries:

   * Names must be valid Scheme symbols.

   * Comments are used, for example, to comment the generated C code
     (1).

   * Comments may be any number of lines, though generally succinct
     comments are preferable(2).

   * Everything is case sensitive.(3)

   * While "_" is a valid character to use in symbols, "-" is preferred

   * Hex numbers are written using Scheme's notation.  Write 255 in hex
     as #xff, not 0xff.  One can also use #bNNN to write boolean
     values.  E.g. #b111 == 7.

   * Except for the `comment' and `attrs' fields and unless otherwise
     specified all fields must be present.

   * Symbols used to be allowed anywhere a string can be used.  This is
     what earlier versions of Guile supported.  Guile is more strict
     now, so this relaxation is gone.  The reverse is generally not
     allowed, strings can't be used in place of symbols.

   * Use `()' or `#f' to indicate "not specified", unless otherwise
     specified.  This is not necessary for `define-foo' elements, one
     can just elide the entry, but it is useful for `define-*-foo' that
     take a fixed number of arguments.  E.g., `define-normal-ifield'.
     Whether to use `()' or `#f' is largely a matter of style.

   ---------- Footnotes ----------

   (1) It is possible to produce a reference manual from `.cpu' files
and such an application wouldn't be a bad idea.

   (2) It would be reasonable to have a short form and a long form of
comment. Either as two entries are as one entry with the short form
separated from the long form via some delimiter (say the first newline).

   (3) ??? This is true in RTL, though some apps add symbols and
convert case that can cause collisions.


File: cgen.info,  Node: RTL Versions,  Next: Top level conditionals,  Prev: Rules and notes,  Up: RTL

3.4 RTL Versions
================

CGEN has minimal support for making changes to the language without
breaking existing ports.  We do not put much effort into this because
over time it can become unmaintainable, but for some changes it is
useful to have a temporary window in which older versions are supported.

* Menu:

* Specifying the RTL version::
* List of supported RTL versions::


File: cgen.info,  Node: Specifying the RTL version,  Next: List of supported RTL versions,  Up: RTL Versions

3.4.1 Specifying the RTL version
--------------------------------

Specify the version of RTL that your cpu description was written to
with `define-rtl-version'.

   Syntax:

     (define-rtl-version major-version minor-version)

   When setting the RTL version, it must be the first thing done in the
description file or the behaviour is undefined.  This includes using or
defining pmacros, the RTL version must be set first.  After the RTL
version is set, if it is changed the behavior is undefined.

   Note that one can still set it to the same version multiple times.
This is useful when the description is spread among several files, and
one is debugging/testing files individually.

   The default RTL version, if `define-rtl-version' is elided, is 0.7.

   The latest RTL version is 0.9:

     (define-rtl-version 0 9)

   Every increment in major and minor versions is generally non-upward
compatible (otherwise the version would not have been incremented -
CGEN does not keep support for older versions long).


File: cgen.info,  Node: List of supported RTL versions,  Prev: Specifying the RTL version,  Up: RTL Versions

3.4.2 List of supported RTL versions
------------------------------------

CGEN currently supports the following RTL versions.

   * 0.7 `(define-rtl-version 0 7)'

     This is the original RTL version.  It is the default if no version
     is specified.  It is supported by CGEN versions 1.0, 1.1, and the
     current development tree.  Support for it will probably be removed
     for the CGEN 1.2 release.

   * 0.8 `(define-rtl-version 0 8)'

     This version changed the syntax for defining keywords.  *Note
     Keywords::.  The `print-name' field was renamed to `enum-prefix'
     and the `prefix' field was renamed to `name-prefix'.

     Previous syntax:

          (define-keyword
            (name keyword-name)
            (comment "description")
            (attrs attribute-list)
            (mode mode-name)
            (print-name "prefix-for-enum-values-with-trailing-dash")
            (prefix "prefix-for-names-in-string-table")
            (values value-list)
          )

     New syntax:

          (define-keyword
            (name keyword-name)
            (comment "description")
            (attrs attribute-list)
            (mode mode-name)
            (enum-prefix "prefix-for-enum-values")
            (name-prefix "prefix-for-names-in-string-table")
            (values value-list)
          )

     Note that `print-name' has been replaced with `enum-prefix' and
     `prefix' has been replaced with `name-prefix'.

     Furthermore, there is also a difference between the behavior of
     `print-name' and `enum-prefix'.  When computing complete enum
     names with `print-name', CGEN adds a `-' between the prefix and
     the enum name.  CGEN does not insert a `-' with `enum-prefix'.

   * 0.9 `(define-rtl-version 0 9)'

     This version changed the prefix of pmacros from `.' to `%'.
     `.pmacro' is changed to `%pmacro'.



File: cgen.info,  Node: Top level conditionals,  Next: Definitions,  Prev: RTL Versions,  Up: RTL

3.5 Top level conditionals
==========================

CGEN supports conditionally defining objects through the use of `if'
and some specialized predicates.  These must appear at the "top level",
i.e., not inside any other expression, except `begin'.

   The following predicates are supported:

   * (keep-isa? (isa-list)) Return "true" if any ISA in `isa-list' is
     being kept.  This is controlled by the `-i' option.

   * (keep-mach? (machine-list)) Return "true" if any machine in
     `machine-list' is being kept.  This is controlled by the `-m'
     option.

   * (application-is? application) Return "true" if the current
     application generator is `application'.  Currently valid
     applications are:

        * DOC: ISA documentation generated from the description file(s).

        * OPCODES: Binutils support

        * GAS-TEST: GAS testsuite generator

        * SID-SIMULATOR: The SID simulator

        * SIMULATOR: The GNU simulator

        * SIM-TEST: The GNU simulator testsuite generator

        * TESTSUITE: The CGEN testsuite

   * (rtl-version-equal? major minor) Return "true" if the RTL version
     specified by the `.cpu' file is `major.minor'.

   * (rtl-version-at-least? major minor) Return "true" if the RTL
     version specified by the `.cpu' file is at least `major.minor'.


   Here's an example from the CGEN testsuite.  It is used to write some
wrappers around a few builtin pmacros that are independent of the
pmacro prefix character.

     (if (rtl-version-at-least? 0 9)
         (begin
           (define-pmacro /begin %begin)
           (define-pmacro /print %print)
           (define-pmacro /dump %dump))
         (begin
           (define-pmacro /begin .begin)
           (define-pmacro /print .print)
           (define-pmacro /dump .dump)))

   Here's an example from the `SH' cpu description.

     (if (keep-isa? (compact))
         (include "sh64-compact.cpu"))

     (if (keep-isa? (media))
         (include "sh64-media.cpu"))


File: cgen.info,  Node: Definitions,  Next: Attributes,  Prev: Top level conditionals,  Up: RTL

3.6 Definitions
===============

Each entry has the same format: `(define-foo arg1 arg2 ...)', where
`foo' designates the type of entry (e.g. `define-insn').  In the
general case each argument is a name/value pair expressed as `(name
value)'.  (*Note: Another style in common use is `:name value' and
doesn't require parentheses.  Maybe that would be a better way to go
here.  The current style is easier to construct from macros though.)

   While the general case is flexible, it also is excessively verbose in
the normal case.  To reduce this verbosity, a second version of most
define-foo's, generally named `define-normal-foo' or
`define-simple-foo', exist that takes a fixed number of positional
arguments.  With pmacros they can be even shortened further to just
their acronym.  E.g. `define-normal-ifield' -> `dnf'.  Ports are free
to write their own preprocessor macros to simplify things further as
desired.  See sections titled "Simplification macros" later in this
chapter.


File: cgen.info,  Node: Attributes,  Next: Architecture variants,  Prev: Definitions,  Up: RTL

3.7 Attributes
==============

Attributes are used throughout for specifying various properties.  For
portability reasons attributes can only have 32 bit integral values
(signed or unsigned).

   There are four kinds of attributes: boolean, integer, enumerated,
and bitset.  Boolean attributes can be achieved via others, but they
occur frequently enough that they are special cased (and one bit can be
used to record them).  Bitset attributes are a useful simplification
when one wants to indicate an object can be in one of many states (e.g.
an instruction may be supported by multiple machines).

   String attributes might be a useful addition.  Another useful
addition might be functional attributes (the attribute is computed at
run-time - currently all attributes are computed at compile time).  One
way to implement functional attributes would be to record the
attributes as byte-code and lazily evaluate them, caching the results
as appropriate.  The syntax has been done to not preclude either as an
upward compatible extension.

   Attributes must be defined before they can be used.  There are
several predefined attributes for entry types that need them
(instruction field, hardware, operand, and instruction).  Predefined
attributes are documented in each relevant section.

   In C applications an enum is created that defines all the attributes.
Applications that wish to have some architecture independent-ness need
the attribute to have the same value across all architectures.  This is
achieved by giving the attribute the INDEX attribute (1), which
specifies the enum value must be fixed across all architectures.

   Convention requires attribute names consist of uppercase letters,
numbers, "-", and "_", and must begin with a letter.  To be consistent
with Scheme, "-" is preferred over "_".

3.7.1 Boolean Attributes
------------------------

Boolean attributes are defined with:

     (define-attr
       (type boolean)
       (for user-list)
       (name attribute-name)
       (comment "attribute comment")
       (attrs attribute-attributes)
       (values #f #t)
       (default #f)
     )

   The default value of boolean attributes is always false.  This can be
relaxed, but it's one extra complication that is currently unnecessary.
Boolean attributes are specified in either of two forms: `(NAME expr)',
`NAME', and `!NAME'.  The first form is the canonical form.  The latter
two are shorthand versions.  `NAME' means "true" and `!NAME' means
"false".  `expr' is either `#f' or `#t'.

   `user-list' is a space separated list of entry types that will use
the attribute.  Possible values are: `attr', `enum', `cpu', `mach',
`model', `ifield', `hardware', `operand', `insn' and `macro-insn'.  If
omitted all are considered users of the attribute.

   The `values' and `default' fields if provided must have the
indicated values.  Usually these fields are elided.

3.7.2 Integer Attributes
------------------------

Integer attributes are defined with:

     (define-attr
       (type integer)
       (for user-list)
       (name attribute-name)
       (comment "attribute comment")
       (attrs attribute-attributes)
       (default integer-value)
     )

   If omitted, the default is 0.

   Integer attributes are specified with `(NAME value)'.

3.7.3 Enumerated Attributes
---------------------------

Enumerated attributes are the same as integer attributes except the
range of possible values is restricted and each value has a name.
Enumerated attributes are defined with

     (define-attr
       (type enum)
       (for user-list)
       (name attribute-name)
       (comment "attribute comment")
       (attrs attribute-attributes)
       (values enum-value1 enum-value2 ...)
       (default default-enum-value)
     )

   If omitted, the default is the first entry in `values'.

   Enum attributes are specified with `(NAME enum-value)'.

3.7.4 Bitset Attributes
-----------------------

Bitset attributes are for situations where you want to indicate
something is a subset of a small set of possibilities.  The MACH
attribute uses this for example to allow specifying which of the
various machines support a particular insn.  (*Note: At present the
maximum number of possibilities is 32.  This is an implementation
restriction which can be relaxed, but there's currently no rush.)

   Bitset attributes are defined with:

     (define-attr
       (type bitset)
       (for user-list)
       (name attribute-name)
       (comment "attribute comment")
       (attrs attribute-attributes)
       (values enum-value1 enum-value2 ...)
       (default default-value1 default-value2 ...)
     )

   The default values must be from the specified values.  The default
must be provided, it may not be omitted.

   Bitset attributes are specified with `(NAME val1 val2 ...)'.

   For backward compatibility they may also be specified with `(NAME
val1,val2,...)' or `(NAME "val1,val2,...")', there must be no spaces in
"`val1,val2,...'" and each value must be a valid Scheme symbol.  Use of
`(NAME val1,val2,...)' is deprecated, and support for it will go away
at some point.

   ---------- Footnotes ----------

   (1) Yes, attributes can have attributes.


File: cgen.info,  Node: Architecture variants,  Next: Model variants,  Prev: Attributes,  Up: RTL

3.8 Architecture variants
=========================

The base architecture and its variants are described in four parts:
`define-arch', `define-isa', `define-cpu', and `define-mach'.

* Menu:

* define-arch::
* define-isa::
* define-cpu::
* define-mach::


File: cgen.info,  Node: define-arch,  Next: define-isa,  Up: Architecture variants

3.8.1 define-arch
-----------------

`define-arch' describes the overall architecture, and must be present.

   The syntax of `define-arch' is:

     (define-arch
       (name architecture-name) ; e.g. m32r
       (comment "description")  ; e.g. "Mitsubishi M32R"
       (attrs attribute-list)
       (default-alignment aligned|unaligned|forced)
       (insn-lsb0? #f|#t)
       (machs mach-name-list)
       (isas isa-name-list)
     )

3.8.1.1 default-alignment
.........................

Specify the default alignment to use when fetching data (and
instructions) from memory.  At present this can't be overridden, but
support can be added if necessary.  The default is `aligned'.

3.8.1.2 insn-lsb0?
..................

Specifies whether the most significant or least significant bit in a
word is bit number 0.  Generally this should conform to the convention
in the architecture manual.  This is independent of endianness and is an
architecture wide specification.  There is no support for using
different bit numbering conventions within an architecture.

   Instruction fields are always numbered beginning with the most
significant bit.  That is, the `start' of a field is always its most
significant bit.  For example, a 4 bit field in the uppermost bits of a
32 bit instruction would have a start/length of (31 4) when insn-lsb0? =
`#t', and (0 4) when insn-lsb0? = `#f'.

3.8.1.3 mach-name-list
......................

The list of names of machines in the architecture.  There should be one
entry for each `define-mach'.

3.8.1.4 isa-name-list
.....................

The list of names of instruction sets in the architecture.  There must
be one for each `define-isa'.  An example of an architecture with more
than one is the ARM which has a 32 bit instruction set and a 16 bit
"Thumb" instruction set (the sizes here refer to instruction size).


File: cgen.info,  Node: define-isa,  Next: define-cpu,  Prev: define-arch,  Up: Architecture variants

3.8.2 define-isa
----------------

`define-isa' describes aspects of the instruction set.  A minimum of
one ISA must be defined.

   The syntax of `define-isa' is:

     (define-isa
       (name isa-name)
       (comment "description")
       (attrs attribute-list)
       (default-insn-word-bitsize n)
       (default-insn-bitsize n)
       (base-insn-bitsize n)
       ; (decode-assist (b0 b1 b2 ...)) ; generally unnecessary
       (liw-insns n)
       (parallel-insns n)
       (condition ifield-name expr)
       (setup-semantics expr)
       ; (decode-splits decode-split-list) ; support temporarily disabled
       ; ??? missing here are fetch/execute specs
     )

3.8.2.1 default-insn-word-bitsize
.................................

Specifies the default size of an instruction word in bits.  This
affects the numbering of field bits in words beyond the base
instruction.  *Note Instruction fields::, for more information.

3.8.2.2 default-insn-bitsize
............................

The default size of an instruction in bits. It is generally the size of
the smallest instruction. It is used when parsing instruction fields.
It is also used by the disassembler to know how many bytes to skip for
unrecognized instructions.

3.8.2.3 base-insn-bitsize
.........................

The minimum size of an instruction, in bits, to fetch during execution.
If the architecture has a variable length instruction set, this is the
size of the initial word to fetch.  There is no need to specify the
maximum length of an instruction, that can be computed from the
instructions.  Examples:

i386
     8

M68k
     16

SPARC
     32

M32R
     32

   The M32R case is interesting because instructions can be 16 or 32
bits.  However instructions on 32 bit boundaries can always be fetched
32 bits at a time as 16 bit instructions always come in pairs.

3.8.2.4 decode-assist
.....................

Override CGEN's heuristics about which bits to initially use to decode
instructions in a simulator.  For example on the SPARC these are bits:
31 30 24 23 22 21 20 19.  The entire decoder can be machine generated,
so this field is entirely optional.  Since the heuristics are quite
good, you should only use this field if you have evidence that you can
pick a better set, in which case the CGEN developers would like to hear
from you!

   ??? It might be useful to provide greater control, but this is
sufficient for now.

   It is okay if the opcode bits are over-specified for some
instructions.  It is also okay if the opcode bits are under-specified
for some instructions.  The machine generated decoder will properly
handle both these situations.  Just pick a useful number of bits that
distinguishes most instructions.  It is usually best to not pick more
than 8 bits to keep the size of the initial decode table down.

   Bit numbering is defined by the `insn-lsb0?' field.

3.8.2.5 liw-insns
.................

The number of instructions the CPU always fetches at once.  This is
intended for architectures like the M32R, and does not refer to a CPU's
ability to pre-fetch instructions.  The default is 1.

3.8.2.6 parallel-insns
......................

The maximum number of instructions the CPU can execute in parallel.  The
default is 1.

   ??? Rename this to `max-parallel-insns'?

3.8.2.7 condition
.................

Some architectures like ARM and ARC conditionally execute every
instruction based on the condition specified by one instruction field.
The `condition' spec exists to support these architectures.
`ifield-name' is the name of the instruction field denoting the
condition and `expression' is an RTL expressions that returns the value
of the condition (false=zero, true=non-zero).

3.8.2.8 setup-semantics
.......................

Specify a statement to be performed prior to executing particular
instructions.  This is used, for example, on the ARM where the value of
the program counter (general register 15) is a function of the
instruction (it is either pc+8 or pc+12, depending on the instruction).

3.8.2.9 decode-splits
.....................

Specify a list of field names and values to split instructions up by.
This is used, for example, on the ARM where the behavior of some
instructions is quite different when the destination register is r15
(the pc).

   The syntax is:

     (decode-splits
       (ifield1-name
        constraints
        ((split1-name (value1 value2 ...)) (split2-name ...)))
       (ifield2-name
        ...)
     )

   `constraints' is work-in-progress and should be `()' for now.

   One copy of each instruction satisfying `constraint' is made for
each specified split.  The semantics of each copy are then simplified
based on the known values of the specified instruction field.


File: cgen.info,  Node: define-cpu,  Next: define-mach,  Prev: define-isa,  Up: Architecture variants

3.8.3 define-cpu
----------------

`define-cpu' defines a "CPU family" which is a programmer specified
collection of related machines.  What constitutes a family is
work-in-progress however it is intended to distinguish things like
sparc32 vs sparc64.  Machines in a family are sufficiently similar that
the simulator semantic code can handle any differences at run time.  At
least that's the current idea.  A minimum of one CPU family must be
defined.  (1)

   The syntax of `define-cpu' is:

     (define-cpu
       (name cpu-name)
       (comment "description")
       (attrs attribute-list)
       (endian big|little|either)
       (insn-endian big|little|either)
       (data-endian big|little|either)
       (float-endian big|little|either)
       (word-bitsize n)
       (insn-chunk-bitsize n)
       (parallel-insns n)
       (file-transform transformation)
     )

3.8.3.1 endian
..............

The endianness of the architecture is one of three values: `big',
`little' and `either'.

   An architecture may have multiple endiannesses, including one for
each of: instructions, integers, and floats (not that that's intended
to be the complete list).  These are specified with `insn-endian',
`data-endian', and `float-endian' respectively.

   Possible values for `insn-endian' are: `big', `little', and
`either'.  If missing, the value is taken from `endian'.

   Possible values for `data-endian' and `float-endian' are: `big',
`big-words', `little', `little-words' and `either'.  If `big-words'
then each word is little-endian.  If `little-words' then each word is
big-endian.  If missing, the value is taken from `endian'.

   ??? Support for these is work-in-progress.  All forms are recognized
by the `.cpu' file reader, but not all are supported internally.

3.8.3.2 word-bitsize
....................

The number of bits in a word.  In GCC, this is `BITS_PER_WORD'.

3.8.3.3 insn-chunk-bitsize
..........................

The number of bits in an instruction word chunk, for purposes of
per-chunk endianness conversion.  The default is zero, meaning no
chunking is required.

3.8.3.4 parallel-insns
......................

This is the same as the `parallel-insns' spec of `define-isa'.  It
allows a CPU family to override the value.

3.8.3.5 file-transform
......................

Specify the file name transformation of generated code.

   Each generated file has a named related to the ISA or CPU family.
Sometimes generated code needs to know the name of another generated
file (e.g. #include's).  At present `file-transform' specifies the
suffix.

   For example, M32R/x generated files have an `x' suffix, as in
`cpux.h' for the `cpu.h' header.  This is indicated with
`(file-transform "x")'.

   ??? Ideally generated code wouldn't need to know anything about file
names.  This breaks down for #include's.  It can be fixed with symlinks
or other means.

   ---------- Footnotes ----------

   (1) FIXME: Using "cpu" in "cpu-family" here is confusing.  Need a
better name.  Maybe just "family"?


File: cgen.info,  Node: define-mach,  Prev: define-cpu,  Up: Architecture variants

3.8.4 define-mach
-----------------

`define-mach' defines a distinct variant of a CPU.  It currently has a
one-to-one correspondence with BFD's "mach number".  A minimum of one
mach must be defined.

   The syntax of `define-mach' is:

     (define-mach
       (name mach-name)
       (comment "description")
       (attrs attribute-list)
       (cpu cpu-family-name)
       (bfd-name "bfd-name")
       (isas isa-name-list)
     )

3.8.4.1 bfd-name
................

The name of the mach as used by BFD.  If not specified the name of the
mach is used.

3.8.4.2 isas
............

List of names of ISA's the machine supports.


File: cgen.info,  Node: Model variants,  Next: Hardware elements,  Prev: Architecture variants,  Up: RTL

3.9 Model variants
==================

For each `machine', as defined here, there is one or more `models'.
There must be at least one model for each machine.  (*Note: There could
be a default, but requiring one doesn't involve that much extra typing
and forces the programmer to at least think about such things.)

     (define-model
       (name model-name)
       (comment "description")
       (attrs attribute-list)
       (mach machine-name)
       (state (variable-name-1 variable-mode-1) ...)
       (unit name "comment" (attributes)
     	issue done state inputs outputs profile)
     )

3.9.1 mach
----------

The name of the machine the model is an implementation of.

3.9.2 state
-----------

A list of variable-name/mode pairs for recording global function unit
state.  For example on the M32R the value is `(state (h-gr UINT))' and
is a bitmask of which register(s) are the targets of loads and thus
subject to load stalls.

3.9.3 unit
----------

Specifies a function unit.  Any number of function units may be
specified.  The `u-exec' unit must be specified as it is the default.

   The syntax is:

       (unit name "comment" (attributes)
          issue done state inputs outputs profile)

   `issue' is the number of operations that may be in progress.  It
originates from GCC function unit specification.  In general the value
should be 1.

   `done' is the latency of the unit.  The value is the number of cycles
until the result is ready.

   `state' has the same syntax as the global model `state' and is a
list of variable-name/mode pairs.

   `inputs' is a list of inputs to the function unit.  Each element is
`(operand-name mode default-value)'.

   `outputs' is a list of outputs of the function unit.  Each element
is `(operand-name mode default-value)'.

   `profile' is an rtl-code sequence that performs function unit
modeling.  At present the only possible value is `()' meaning invoke a
user supplied function named `<cpu>_model_<mach>_<unit>'.

   The current function unit specification is a first pass in order to
achieve something that moderately works for the intended purpose (cycle
counting on the simulator).  Something more elaborate is on the todo
list but there is currently no schedule for it.  The new specification
must try to be application independent.  Some known applications are:
cycle counting in the simulator, code scheduling in a compiler, and code
scheduling in a JIT simulator (where speed of analysis can be more
important than getting an optimum schedule).

   The inputs/outputs fields are how elements in the semantic code are
mapped to function units.  Each input and output has a name that
corresponds with the name of the operand in the semantics.  Where there
is no correspondence, a mapping can be made in the unit specification
of the instruction (see the subsection titled "Timing").

   Another way to achieve the correspondence is to create separate
function units that contain the desired input/output names.  For
example on the M32R the u-exec unit is defined as:

     (unit u-exec "Execution Unit" ()
        1 1 ; issue done
        () ; state
        ((sr INT -1) (sr2 INT -1)) ; inputs
        ((dr INT -1)) ; outputs
        () ; profile action (default)
     )

   This handles instructions that use sr, sr2 and dr as operands.  A
second function unit called `u-cmp' is defined as:

     (unit u-cmp "Compare Unit" ()
        1 1 ; issue done
        () ; state
        ((src1 INT -1) (src2 INT -1)) ; inputs
        () ; outputs
        () ; profile action (default)
     )

   This handles instructions that use src1 and src2 as operands.  The
organization of units is arbitrary.  On the M32R, src1/src2 instructions
are typically compare instructions so a separate function unit was
created for them.  Current limitations require that each hardware item
behind the operands must be marked with the attribute `PROFILE' and the
hardware item must not be scalar.


File: cgen.info,  Node: Hardware elements,  Next: Instruction fields,  Prev: Model variants,  Up: RTL

3.10 Hardware elements
======================

The elements of hardware that make up a CPU are defined with
`define-hardware'.  Examples of hardware elements include registers,
condition bits, immediate constants and memory.

   Instruction fields that provide numerical values ("immediate
constants") aren't really elements of the hardware, but it simplifies
things to think of them this way.  Think of them as _constant
generators_(1).

   Hardware elements are defined with:

     (define-hardware
       (name hardware-name)
       (comment "description")
       (attrs attribute-list)
       (semantic-name hardware-semantic-name)
       (type type-name type-arg1 type-arg2 ...)
       (indices index-type index-arg1 index-arg2 ...)
       (values values-type values-arg1 values-arg2 ...)
       (handlers handler1 handler2 ...)
       (get (args) expression)
       (set (args) expression)
       (layout layout-list)
     )

   The only required elements are `name' and `type'.  Convention
requires `hardware-name' begin with `h-'.

3.10.1 attrs
------------

List of attributes. There are several predefined hardware attributes:

   - MACH

     A bitset attribute used to specify which machines have this
     hardware element.  Do not specify the MACH attribute if the value
     is "all machs".

     Usage: `(MACH mach1,mach2,...)' There must be no spaces in
     "`mach1,mach2,...'".

   - CACHE-ADDR

     A hint to the simulator semantic code generator to tell it it can
     record the address of a selected register in an array of
     registers.  This speeds up simulation by moving the array
     computation to extraction time.  This attribute is only useful to
     register arrays and cannot be specified with `VIRTUAL' (???
     revisit).

   - PROFILE

     This attribute must be present for hardware elements to which
     references are profiled.  Beware, this is work-in-progress.  If
     you use this attribute it is likely you have to hack CGEN.
     (Please submit patches.)

   - VIRTUAL

     The hardware element doesn't require any storage.  This is used
     when you want a value that is derived from some other value.  If
     `VIRTUAL' is specified, `get' and `set' specs must be provided.

3.10.2 type
-----------

This is the type of hardware.  Current values are: `pc', `register',
`memory', and `immediate'.

   For `pc', see *Note Program counter::.

   For registers the syntax is one of:

     `(register mode [(number)])'
     `(register (mode bits) [(number)])'

   where `(number)' is the number of registers and is optional. If
omitted, the default is `(1)'.  The second form is useful for
describing registers with an odd (as in unusual) number of bits.
`mode' for the second form must be one of `INT' or `UINT'.  Since these
two modes don't have an implicit size, they cannot be used for the
first form.

   For memory the syntax is:

     `(memory mode (size))'

   where `(size)' is the size of the memory in `mode' units.  In
general `mode' should be `QI'.

   For immediates the syntax is one of

     `(immediate mode)'
     `(immediate (mode bits))'

   The second form is for values for which a mode of that size doesn't
exist.  `mode' for the second form must be one of `INT' or `UINT'.
Since these two modes don't have an implicit size, they cannot be used
for the first form.

   ??? There's no real reason why a mode like SI can't be used for
odd-sized immediate values.  The `bits' field indicates the size and
the `mode' field indicates the mode in which the value will be used, as
well as its signedness.  This would allow removing INT/UINT for this
purpose.  On the other hand, a non-width specific mode allows
applications to choose one (a simulator might prefer to store
immediates in an `int' rather than, say, char if the specified mode was
`QI').

3.10.3 indices
--------------

Specify names for individual elements with the `indices' spec.  It is
only valid for registers with more than one element.

   The syntax is:

     `(indices index-type arg1 arg2 ...)'

   where `index-type' specifies the kind of index and `arg1 arg2 ...'
are arguments to `index-type'.

   There are two supported values for `index-type': `keyword' and
`extern-keyword'.  The difference is that indices defined with
`keyword' are kept internal to the hardware element's definition and
are not usable elsewhere, whereas `extern-keyword' specifies a set of
indices defined elsewhere with `define-keyword'.

3.10.3.1 keyword
................

     `(indices keyword name-prefix ((name1 value1) (name2 value2) ...))'

   `name-prefix' is the assembler prefix common to each of the index
names, and is added to name in the generated lookup table.  For
example, SPARC registers usually begin with `"%"'.

   Each `(name value)' pair maps a name with an index number.  An index
can be specified multiple times, for example, when a register has
multiple names.

   There may be gaps in the index list, e.g. for invalid/reserved
registers.

   No enum is defined for keywords defined this way.  If you want an
enum use `define-keyword' and `extern-keyword'.

   Example from Thumb:

     (define-hardware
       (name h-gr-t)
       (comment "Thumb's general purpose registers")
       (attrs (ISA thumb) VIRTUAL) ; ??? CACHE-ADDR should be doable
       (type register WI (8))
       (indices keyword ""
     	   ((r0 0) (r1 1) (r2 2) (r3 3) (r4 4) (r5 5) (r6 6) (r7 7)))
       (get (regno) (reg h-gr regno))
       (set (regno newval) (set (reg h-gr regno) newval))
     )

3.10.3.2 extern-keyword
.......................

     `(indices extern-keyword keyword-name)'

   Often one wants to make the keywords available for general use, i.e.
to arbitrary tools.  *Note Keywords::.  When the collection of indices
is defined with `define-keyword' refer to it in the `indices' field
with `extern-keyword'.

   Example from M32R:

     (define-keyword
       (name gr-names)
       (enum-prefix H-GR-)
       (values (fp 13) (lr 14) (sp 15)
     	  (r0 0) (r1 1) (r2 2) (r3 3) (r4 4) (r5 5) (r6 6) (r7 7)
     	  (r8 8) (r9 9) (r10 10) (r11 11) (r12 12) (r13 13) (r14 14) (r15 15))
     )

     (define-hardware
       (name h-gr)
       (comment "general registers")
       (attrs PROFILE CACHE-ADDR)
       (type register WI (16))
       (indices extern-keyword gr-names)
     )

3.10.4 values
-------------

Specify a list of valid values with the `values' spec.

   The syntax is identical to the syntax for `indices'.  It is only
valid for immediates.

   Example from sparc64:

     (define-hardware
       (name h-p)
       (comment "prediction bit")
       (attrs (MACH64))
       (type immediate (UINT 1))
       (values keyword "" (("" 0) (",pf" 0) (",pt" 1)))
     )

3.10.5 handlers
---------------

The `handlers' spec is an escape hatch for indicating when a programmer
supplied routine must be called to perform a function.

   The syntax is:

     `(handlers (handler-name1 "function_name1")
                     (handler-name2 "function_name2")
                     ...)'

   `handler-name' must be one of `parse' or `print'.  How
`function_name' is used is application specific, but in general it is
the name of a function to call.  The only application that uses this at
present is Opcodes.  See the Opcodes documentation for a description of
each function's expected prototype.

3.10.6 get
----------

Specify special processing to be performed when a value is read with
the `get' spec.

   The syntax for scalar registers is:

     `(get () (expression))'

   The syntax for vector registers is:

     `(get (index) (expression))'

   `expression' is an RTL expression that computes the value to return.
The mode of the result must be the mode of the register.

   `index' is the name of the index as it appears in `expression'.

   At present, `sequence', `parallel', `do-count' and `case'
expressions are not allowed here.

3.10.7 set
----------

Specify special processing to be performed when a value is written with
the `set' spec.

   The syntax for scalar registers is:

     `(set (newval) (expression))'

   The syntax for vector registers is:

     `(set (index newval) (expression))'

   `expression' is an RTL expression that stores `newval' in the
register.  This may involve storing values in other registers as well.
`expression' must be one of `set', `if', `sequence', or `case'.

   `index' is the name of the index as it appears in `expression'.

3.10.8 layout
-------------

For specific hardware elements, specifying a layout is an alternative
to providing getter/setter specs.

   At present this applies to only `register' hardware elements, but
not the `pc'.

   Some registers are a collection of bits with different meanings.  It
is often useful to define each field of such a register as its own
register.  The `layout' spec can then be used to build up the outer
register from the individual register fields.

   The fields are written from least to most significant.  Each field
is either the name of another hardware register, or a list of (value
length) to specify hardwired bits.

   A typical example is a "flags" register.  Here is an example for a
fictitious flags register.  It is eight bits wide, with the lower four
bits having defined values, and the upper four bits hardwired to zero.

     (dsh h-cf "carry flag"    () (register BI))
     (dsh h-sf "sign flag"     () (register BI))
     (dsh h-of "overflow flag" () (register BI))
     (dsh h-zf "zero flag"     () (register BI))
     (define-hardware
       (name flags)
       (type register QI)
       (layout (h-cf h-sf h-of h-zf (0 4)))
     )

3.10.9 Predefined hardware elements
-----------------------------------

Several hardware types are predefined:

`h-uint'
     unsigned integer

`h-sint'
     signed integer

`h-memory'
     main memory, where "main" is loosely defined

`h-addr'
     data address (data only)

`h-iaddr'
     instruction address (instructions only)

3.10.10 Program counter
-----------------------

The program counter must be defined and is not a builtin.  If get/set
specs are not required, define it as:

     (dnh h-pc "program counter" (PC) (pc) () () ())

   If get/set specs are required, define it as:

     (define-hardware
       (name h-pc)
       (comment "<ARCH> program counter")
       (attrs PC)
       (type pc)
       (get () <insert get code here>)
       (set (newval) <insert set code here>)
     )

   If the architecture has multiple instruction sets, all must be
specified.  If they're not, the default is the first one which is often
not what you want.  Here's an example from `arm.cpu':

     (define-hardware
       (name h-pc)
       (comment "ARM program counter (h-gr reg 15)")
       (attrs PC (ISA arm,thumb))
       (type pc)
       (set (newval)
            (if (reg h-tbit)
     	   (set (raw-reg SI h-pc) (and newval -2))
     	   (set (raw-reg SI h-pc) (and newval -4))))
     )

3.10.11 Simplification macros
-----------------------------

To simplify `.cpu' files several pmacros are provided.

   The `define-normal-hardware' pmacro (with alias `dnh') takes a fixed
set of positional arguments for the typical hardware element.  The
syntax is:

   `(dnh name comment attributes type indices values handlers)'

   Example:

     (dnh h-gr "general registers"
          () ; attributes
          (register WI (16))
          (keyword "" ((fp 13) (sp 15) (lr 14)
                       (r0 0) (r1 1) (r2 2) (r3 3)
                       (r4 4) (r5 5) (r6 6) (r7 7)
                       (r8 8) (r9 9) (r10 10) (r11 11)
                       (r12 12) (r13 13) (r14 14) (r15 15)))
          () ()
     )

   This defines an array of 16 registers of mode `WI' ("word int").
The names of the registers are `r0...r15', and registers 13, 14 and 15
also have the names `fp', `lr' and `sp' respectively.

   Scalar registers with no special requirements occur frequently.
Macro `define-simple-hardware' (with alias `dsh') is identical to `dnh'
except does not include the `indices', `values', or `handlers' specs.

     (dsh h-ibit "interrupt enable bit" () (register BI))

   ---------- Footnotes ----------

   (1) A term borrowed from the book on the Bulldog compiler and
perhaps other sources.


File: cgen.info,  Node: Instruction fields,  Next: Enumerated constants,  Prev: Hardware elements,  Up: RTL

3.11 Instruction fields
=======================

Instruction fields (ifields) define the raw bitfields of each
instruction.  Minimal semantic meaning is attributed to them.  Support
is provided for mapping to and from the raw bit pattern and the usable
contents, and other simple manipulations.  (1)

   Instruction fields must be uniquely named within an instruction set,
but different instruction sets (ISAs) may have ifields with the same
name.

   The syntax for defining instruction fields is:

     (define-ifield
       (name field-name)
       (comment "description")
       (attrs attribute-list)
       (word-offset word-offset-in-bits)
       (word-length word-length-in-bits)
       (start starting-bit-number)
       (length number-of-bits)
       (follows ifield-name)
       (mode mode-name)
       (encode (value pc) (rtx to describe encoding))
       (decode (value pc) (rtx to describe decoding))
     )

   The required elements are: `name', `start', `length'.  (2)

   Convention requires `field-name' begin with `f-'.

3.11.1 attrs
------------

There are several predefined instruction field attributes:

`PCREL-ADDR'
     The field contains a PC relative address.  Various CPUs have
     various offsets from the PC from which the address is calculated.
     This is specified in the encode and decode sections.

`ABS-ADDR'
     The field contains an absolute address.

`SIGN-OPT'
     The field has an optional sign.  It is sign-extended during
     extraction. Allowable values are -2^(n-1) to (2^n)-1.

`RESERVED'
     The field is marked as "reserved" by the architecture.  This is an
     informational attribute.  Tools may use it to validate programs,
     either statically or dynamically.

`VIRTUAL'
     The field does not directly contribute to the instruction's value.
     This is used to simplify semantic or assembler descriptions where
     a field's value is based on other values.  Multi-ifields are
     always virtual.

3.11.2 word-offset
------------------

The offset in bits from the start of the instruction to the word
containing the field.  This must be a multiple of eight.

   Either both of `word-offset' and `word-length' must be specified or
neither of them must be specified.  The presence of `word-offset' means
the long form of specifying the field's position is being used.  If
absent then the short form is being used and the value for
`word-offset' is encoded in `start'.

3.11.3 word-length
------------------

The length in bits of the word containing the field.  This must be a
multiple of eight.

3.11.4 start
------------

The bit number of the field's most significant bit in the instruction.
Bit numbering is determined by the `insn-lsb0?' field of `define-arch'.

   If using the long form of specifying the field's position (i.e.,
`word-offset' is specified) then this value is the value within the
containing word.  If using the short form then this value includes the
word offset.  See the Porting document for more info (*note Writing
define-ifield::).

3.11.5 length
-------------

The number of bits in the field.  The field must be contiguous.  For
non-contiguous instruction fields use "multi-ifields".

3.11.6 follows
--------------

Optional.  Experimental.  This should not be used for the specification
of RISC-like architectures.  It is an experiment in supporting
CISC-like architectures.  The argument is the name of the ifield or
operand that immediately precedes this one.  In general the argument is
an "anyof" operand.  The `follows' spec allows subsequent ifields to
"float".

3.11.7 mode
-----------

The mode the value is to be interpreted in.  Usually this is `INT' or
`UINT'.

   The `length' field specifies the number of bits in the field, and
the `mode' field indicates the mode in which the value will be used, as
well as its signedness.  This would allow removing INT/UINT for this
purpose.  On the other hand, a non-width specific mode allows
applications to choose one (a simulator might prefer to store
immediates in an `int' rather than, say, char if the specified mode was
`QI').

3.11.8 encode
-------------

An expression to apply to convert from usable values to raw field
values.  The syntax is `(encode (value pc) expression)' or more
generally `(encode ((<mode1> value) (IAI pc)) <expression>)', where
`<mode1>' is the mode of the "incoming" value, and `<expression>' is an
rtx to convert `value' to something that can be stored in the field.

   Example:

     (encode ((SF value) (IAI pc))
     	(cond WI
     	      ((eq value (const SF 1.0)) (const 0))
     	      ((eq value (const SF 0.5)) (const 1))
     	      ((eq value (const SF -1.0)) (const 2))
     	      ((eq value (const SF 2.0)) (const 3))
     	      (else (error "invalid floating point value for field foo"))))

   In this example four floating point immediate values are represented
in a field of two bits.  The above might be expanded to a series of
`if' statements or the generator could determine a `switch' statement
is more appropriate.

3.11.9 decode
-------------

An expression to apply to convert from raw field values to usable
values.  The syntax is `(decode (value pc) expression)' or more
generally `(decode ((<mode1> value) (IAI pc)) <expression>)', where
`<mode1>' is the mode of the "incoming" value, and `<expression>' is an
rtx to convert `value' to something usable.

   Example:

     (decode ((WI value) (IAI pc))
     	(cond SF
     	      ((eq value 0) (const SF 1.0))
     	      ((eq value 1) (const SF 0.5))
     	      ((eq value 2) (const SF -1.0))
     	      ((eq value 3) (const SF 2.0))))

   There's no need to provide an error case as presumably `value' would
never have an invalid value, though certainly one could provide an
error case if one wanted to.

3.11.10 Non-contiguous fields
-----------------------------

Non-contiguous fields (e.g. sparc64's 16 bit displacement field) are
built on top of support for contiguous fields.  The syntax for defining
such fields is:

     (define-multi-ifield
       (name field-name)
       (comment "description")
       (attrs attribute-list)
       (mode mode-name)
       (subfields field1-name field2-name ...)
       (insert (code to set each subfield))
       (extract (code to set field from subfields))
       (encode (value pc) (rtx to describe encoding))
       (decode (value pc) (rtx to describe decoding))
     )

   The required elements are: `name', `subfields'.

   Example:

     (define-multi-ifield
       (name f-i20)
       (comment "20 bit unsigned")
       (attrs)
       (mode UINT)
       (subfields f-i20-4 f-i20-16)
       (insert (sequence ()
                         (set (ifield f-i20-4)  (srl (ifield f-i20) (const 16)))
                         (set (ifield f-i20-16) (and (ifield f-i20) (const #xffff)))
                         ))
       (extract (sequence ()
                          (set (ifield f-i20) (or (sll (ifield f-i20-4) (const 16))
                                                  (ifield f-i20-16)))
                          ))
     )

3.11.10.1 subfields
...................

The names of the already defined fields that make up the multi-ifield.

3.11.10.2 insert
................

Code to set the subfields from the multi-ifield. All fields are referred
to with `(ifield <name>)'.

3.11.10.3 extract
.................

Code to set the multi-ifield from the subfields. All fields are referred
to with `(ifield <name>)'.

3.11.11 Simplification macros
-----------------------------

To simplify `.cpu' files several pmacros are provided.

   The `define-normal-ifield' pmacro (with alias `dnf') takes a fixed
set of positional arguments for the typical instruction field.  The
syntax is:

   `(dnf name comment attributes start length)'

   Example:

     (dnf f-r1 "register r1" () 4 4)

   This defines a field called `f-r1' that is an unsigned field of 4
bits beginning at bit 4.  All fields defined with `dnf' are unsigned.

   The `df' pmacro adds `mode', `encode', and `decode' elements.

   The syntax of `df' is:

   `(df name comment attributes start length mode encode decode)'

   Example:

     (df f-disp8
         "disp8, slot unknown" (PCREL-ADDR)
         8 8 INT
         ((value pc) (sra WI (sub WI value (and WI pc (const -4))) (const 2)))
         ((value pc) (add WI (sll WI value (const 2)) (and WI pc (const -4)))))

   This defines a field called `f-disp8' that is a signed PC-relative
address beginning at bit 8 of size 8 bits that is left shifted by 2.

   The macro `define-normal-multi-ifield' (with alias `dnmf') takes a
fixed set of positional arguments for the typical multi-ifield.  The
syntax is:

   `(dnmf name comment attributes mode subfields insert extract)'

   The macro `dsmf' takes a fixed set of positional arguments for
simple multi-ifields.  The syntax is:

   `(dsmf name comment attributes mode subfields)'

   ---------- Footnotes ----------

   (1) Whether to also provide a way to specify instruction formats is
not yet clear.  Currently they are computed from the instructions, so
there's no current *need* to provided them.  However, providing the
ability as an option may simplify other tools CGEN is used to generate.
This simplification would come in the form of giving known names to
the formats which CPU reference manuals often do.  Pre-specified
instruction formats may also simplify expression of more complicated
instruction sets.  Providing instruction formats may also simplify the
support of really complex ISAs like i386 and m68k).

   (2) Positional specification simplifies instruction description
somewhat in that there is no required order of fields, and a disjunct
set of fields can be referred to as one.  On the other hand it can
require knowledge of the length of the instruction which is
inappropriate in cases like the M32R where the main fields have the
same name and "position" regardless of the length of the instruction.
Moving positional specification into instruction formats, whether
machine generated or programmer specified, may be done.


File: cgen.info,  Node: Enumerated constants,  Next: Keywords,  Prev: Instruction fields,  Up: RTL

3.12 Enumerated constants
=========================

Enumerated constants (_enums_) are important enough in instruction set
descriptions that they are given special treatment.  Enums are defined
with:

     (define-enum
       (name enum-name)
       (comment "description")
       (attrs attribute-list)
       (prefix prefix)
       (values val1 val2 ...)
     )

   Enums in opcode fields are further enhanced by specifying the opcode
field they are used in.  This allows the enum's name to be specified in
an instruction's `format' entry.

   Instruction enums are defined with `define-insn-enum':

     (define-insn-enum
       (name enum-name)
       (comment "description")
       (attrs attribute-list)
       (ifield ifield-name)
       (prefix prefix)
       (values val1 val2 ...)
     )

   _define-insn-enum is currently not provided, use
define-normal-insn-enum instead_.  *Note define-normal-insn-enum:
a-define-normal-insn-enum.

3.12.1 prefix
-------------

Convention requires each enum value to be prefixed with the same text.
Rather than specifying the prefix in each entry, it is specified once,
here.  Convention requires `prefix' not contain any lowercase
characters.  You generally want to end `prefix' with `-' or `_' as the
complete name of each enum value is `prefix' + `value-name'.  The
convention is to use `-', though this convention is not adhered to as
well as the other conventions.

   The default value is `""'.

3.12.2 ifield
-------------

The name of the instruction field that the enum is intended for.  This
must be a simple ifield, not a multi-ifield.

3.12.3 values
-------------

A list of possible values.  Each element has one of the following forms:

   * `name'

   * `(name)'

   * `(name value)'

   * `(name - (attribute-list))'

   * `(name value (attribute-list))'

   The syntax for numbers is Scheme's, so hex numbers are `#xnnnn'.  A
value of `-' means use the next value (previous value plus 1).

   Enum values currently always have mode `INT'.

   Example:

     (values "a" ("b") ("c" #x12)
     	("d" - (sanitize foo)) ("e" #x1234 (sanitize bar)))

3.12.4 Simplification macros
----------------------------

To simplify `.cpu' files several pmacros are provided.

   The `define-normal-enum' pmacro takes a fixed set of positional
arguments for the typical enum.  The syntax is:

   `(define-normal-enum name comment attrs prefix vals)'

   The `define-normal-insn-enum' pmacro takes a fixed set of positional
arguments for the typical instruction enum.  The syntax is:

   `(define-normal-insn-enum name comment attrs prefix ifield vals)'

   Example:

     (dnf f-op1 "op1" () 0 4)
     (define-normal-insn-enum insn-op1 "insn format enums" () OP1_ f-op1
       (.map .str (.iota 16))
     )

   This defines an instruction enum for field `f-op1' with values
OP1_0, OP1_1, ..., OP1_15.  These values can be directly used in
instruction format specs.  This applies to "instruction enums" only.
One can use normal enums in instruction format specs but one needs to
explicitly specify the ifield, e.g. (f-op1 OP1_0).


File: cgen.info,  Node: Keywords,  Next: Instruction operands,  Prev: Enumerated constants,  Up: RTL

3.13 Keywords
=============

Keywords are like enums, *Note Enumerated constants::, but they also
cause a table of names of each value to be generated.  This is useful
for things like registers where you want arbitrary tools to have access
to the table of names.

   The syntax for defining keywords changed from RTL version 0.7 to RTL
version 0.8.  *Note RTL Versions::.

   RTL version 0.7 syntax:

     (define-keyword
       (name keyword-name)
       (comment "description")
       (attrs attribute-list)
       (mode mode-name)
       (print-name "prefix-for-enum-values-without-trailing-dash")
       (prefix "prefix-for-names-in-string-table")
       (values value-list)
     )

   RTL version 0.8 syntax:

     (define-keyword
       (name keyword-name)
       (comment "description")
       (attrs attribute-list)
       (mode mode-name)
       (enum-prefix "prefix-for-enum-values")
       (name-prefix "prefix-for-names-in-string-table")
       (values value-list)
     )

   Note that `print-name' has been replaced with `enum-prefix' and
`prefix' has been replaced with `name-prefix'.

   Furthermore, there is also a difference between the behavior of
`print-name' and `enum-prefix'.  When computing complete enum names
with `print-name', CGEN adds a `-' between the prefix and the enum name.
CGEN does not insert a `-' with `enum-prefix'.

3.13.1 mode
-----------

This is the mode to reference and record the keyword's value in.  The
default is `INT'.  It is normally not necessary to use something else.

3.13.2 print-name
-----------------

_NOTE: This is for RTL version 0.7 only._

   This value plus a trailing `-' is passed as the `prefix' parameter
when defining the corresponding enum.  *Note Enumerated constants::.

   Convention requires `print-name' not contain any lowercase
characters.

   The default value is the keyword's name in uppercase.

3.13.3 prefix
-------------

_NOTE: This is for RTL version 0.7 only._

   `prefix' is the assembler prefix common to each of the index names,
and is added to name in the generated lookup table.  For example, SPARC
registers usually begin with `"%"'.  It is _not_ added to the
corresponding enum value names.

   The default value is `""'.

3.13.4 enum-prefix
------------------

_NOTE: This is for RTL version 0.8 and higher.  You must specify the
RTL version at the top of the description file._

   This value is passed as the `prefix' parameter when defining the
corresponding enum.  *Note Enumerated constants::.

   _NOTE:_ Unlike `print-name' in RTL version `0.7', `-' is not
appended when defining the corresponding enum.

   Convention requires `enum-prefix' not contain any lowercase
characters.

   The default value is the keyword's name in uppercase + `-'.

3.13.5 name-prefix
------------------

_NOTE: This is for RTL version 0.8 and higher.  You must specify the
RTL version at the top of the description file._

   `name-prefix' is the assembler prefix common to each of the index
names, and is added to name in the generated lookup table.  For
example, SPARC registers usually begin with `"%"'.  It is _not_ added
to the corresponding enum value names.

   The default value is `""'.

3.13.6 values
-------------

The `values' field has the same syntax as the `values' field of
`define-enum'.  *Note Enum Values: a-enum-values.

   Example from M32R:

     (define-keyword
       (name gr-names)
       (enum-prefix H-GR-)
       (values (fp 13) (lr 14) (sp 15)
     	  (r0 0) (r1 1) (r2 2) (r3 3) (r4 4) (r5 5) (r6 6) (r7 7)
     	  (r8 8) (r9 9) (r10 10) (r11 11) (r12 12) (r13 13) (r14 14) (r15 15))
     )

   Referencing enum values from this keyword in the .cpu file would use
`H-GR-' + `register-name'.  E.g., H-GR-r12.


File: cgen.info,  Node: Instruction operands,  Next: Derived operands,  Prev: Keywords,  Up: RTL

3.14 Instruction operands
=========================

Instruction operands provide:

   * a layer between the assembler and the raw hardware description

   * the main means of making an instruction's fields useful to the
     semantic code

   Instruction operands must be uniquely named within an instruction
set, but different instruction sets (ISAs) may have operands with the
same name.

   The syntax for defining an operand is:

     (define-operand
       (name operand-name)
       (comment "description")
       (attrs attribute-list)
       (type hardware-element)
       (mode mode-name)
       (index instruction-field)
       (handlers handler-spec)
       (getter getter-spec)
       (setter setter-spec)
     )

   The required elements are: `name', `type', `mode', and if `type' is
not a scaler `index'.

3.14.1 name
-----------

This is the name of the operand as a Scheme symbol.  The name choice is
fairly important as it is used in instruction syntax entries,
instruction format entries, and semantic expressions.  It can't collide
with symbols used in semantic expressions (e.g. `and', `set', etc).

   The convention is that operands have no prefix (whereas ifields begin
with `f-' and hardware elements begin with `h-').  A prefix like `o-'
would avoid collisions with other semantic elements, but operands are
used often enough that any prefix is a hassle.

   Note that if you _do_ decide to prefix operand names, e.g. use a
style like `o-foo', then you will need to remember to use the
`${o-foo}' form in the assembler syntax and not the `$o-foo' form
because the latter only takes alphanumeric characters.  *Note syntax:
assembler-syntax.

3.14.2 attrs
------------

A list of attributes. In addition to attributes defined for the operand,
an operand inherits the attributes of its instruction field. There are
several predefined operand attributes:

`NEGATIVE'
     The operand contains negative values (not used yet so definition is
     still nebulous.

`RELAX'
     This operand contains the changeable field (usually a branch
     address) of a relaxable/relaxed instruction.

`SEM-ONLY'
     Use the SEM-ONLY attribute for cases where the operand will only
     be used in semantic specification, and not assembly code
     specification.  A typical example is condition codes.

   To refer to a hardware element in semantic code one must either use
an operand or one of reg/mem/const.  Operands generally exist to map
instruction fields to the selected hardware element and are easier to
use in semantic code than referring to the hardware element directly
(e.g. `sr' is easier to type and read than `(reg h-gr <index>)').
Example:

       (dnop condbit "condition bit" (SEM-ONLY) h-cond f-nil)

   `f-nil' is the value to use when there is no instruction field

3.14.3 type
-----------

The hardware element this operand applies to. This must be the name of a
hardware element.

3.14.4 mode
-----------

The mode the value is to be interpreted in.

3.14.5 index
------------

The index of the hardware element. This is used to mate the hardware
element with the instruction field that selects it, and must be the name
of an ifield entry. (*Note: The index may be other things besides
ifields in the future.)  It must not be a multi-ifield, currently.

3.14.6 handlers
---------------

Sometimes it's necessary to escape to C to parse assembler, or print a
value.  This field is an escape hatch to implement this.  The syntax is:

   `(handlers handler-spec)'

   where `handler-spec' is one or more of:

   `(parse "function_suffix")' - a call to function
`parse_<function_suffix>' is generated.

   `(print "function_suffix")' - a call to function
`print_<function_suffix>' is generated.

   These functions are intended to be provided in a separate `.opc'
file.  The prototype of a parse function depends on the hardware type.
See `cpu/*.opc' for examples.

   For integer it is:

     static const char *
     parse_foo (CGEN_CPU_DESC cd,
     	   const char **strp,
     	   int opindex,
     	   unsigned long *valuep);

   `cd' is the result of `<arch>_cgen_cpu_open'.  `strp' is a pointer
to a pointer to the assembler and is updated by the function.
`opindex' is ???.  `valuep' is a pointer to where to record the parsed
value.  If a relocation is needed, it is queued with a call to ???.
Queued relocations are processed after the instruction has been parsed.

   The result is an error message or NULL if successful.

   The prototype of a print function depends on the hardware type.  See
`cpu/*.opc' for examples. For integers it is:

     void print_foo (CGEN_CPU_DESC cd,
                     PTR dis_info,
                     long value,
                     unsigned int attrs,
                     bfd_vma pc,
                     int length);

   `cd' is the result of `<arch>_cgen_cpu_open'.  `ptr' is the `info'
argument to print_insn_<arch>.  `value' is the value to be printed.
`attrs' is the set of boolean attributes.  `pc' is the PC value of the
instruction.  `length' is the length of the instruction.

   Actual printing is done by calling `((disassemble_info *)
dis_info)->fprintf_func'.

3.14.7 Simplification macros
----------------------------

To simplify `.cpu' files several pmacros are provided.

   The `define-normal-operand') pmacro (with alias `dno') takes a fixed
set of positional arguments for the typical operand.

   There is also the `dnop' pmacro, it is an alias of `dno'.

   The syntax of `dno' is:

   `(dno name comment attrs type index)'

   Example:

     (dno sr "source register" () h-gr f-r2)

   This defines an operand name `sr' that is an `h-gr' register indexed
by the `f-r2' ifield.


File: cgen.info,  Node: Derived operands,  Next: Instructions,  Prev: Instruction operands,  Up: RTL

3.15 Derived operands
=====================

Derived operands are an experiment in supporting the addressing modes of
CISC-like architectures.  Addressing modes are difficult to support as
they essentially increase the number of instructions in the architecture
by an order of magnitude.  Defining all the variants requires something
in addition to the RISC-like architecture support.  The theory is that
since CISC-like instructions are basically "normal" instructions with
complex operands the place to add the necessary support is in the
operands.

   Two kinds of operands exist to support CISC-like cpus, and they work
together.  "derived-operands" describe one variant of a complex
argument, and "anyof" operands group them together.

   The syntax for defining derived operands is:

     (define-derived-operand
       (name operand-name)
       (comment "description")
       (attrs attribute-list)
       (mode mode-name)
       (args arg1-operand-name arg2-operand-name ...)
       (syntax "syntax")
       (base-ifield ifield-name)
       (encoding (+ arg1-operand-name arg2-operand-name ...))
       (ifield-assertion expression)
       (getter expression)
       (setter expression)
     )

   The syntax for defining anyof operands is:

     (define-anyof-operand
       (name operand-name)
       (comment "description")
       (attrs attribute-list)
       (mode mode-name)
       (base-ifield ifield-name)
       (choices derived-operand1-name derived-operand2-name ...)
     )

3.15.1 mode
-----------

The name of the mode of the operand.

3.15.2 args
-----------

List of names of operands the derived operand uses.  The operands must
already be defined.  The argument operands can be any kind of operand:
normal, derived, anyof.

3.15.3 syntax
-------------

Assembler syntax of the operand.

   ??? This part needs more work.  Addressing mode specification in
assembler needn't be localized to the vicinity of the operand.

3.15.4 base-ifield
------------------

The name of the instruction field common to all related derived
operands.  Here related means "used by the same `anyof' operand".

3.15.5 encoding
---------------

The machine encoding of the operand.

3.15.6 ifield-assertion
-----------------------

An assertion of what values any instruction fields will or will not have
in the containing instruction.

   The syntax of the assertion is a restricted subset of RTL.  It may
only contain `andif', `eq', `ne', and may only use scalar instruction
fields (1) and integers as operands.  Furthermore, ifields must be
specified in the first operand of `eq', `ne'.

   As a degenerate case, a single non-zero integer, is also supported,
meaning the assertion passes.

   In addition, the assertion may also use `member'.

   Syntax: `(member ifield-name (number-list value1 [value2 ...]))' (2)

   The result of `member' is one if the value of the ifield is a member
of the list `(value1 [value2 ...])'.  Otherwise the result is zero.

   If the result of the assertion is non-zero, the assertion passes.
Otherwise it fails, and the instruction is not selected for that
particular bit pattern.

3.15.7 getter
-------------

RTL expression to get the value of the operand.  All operands refered
to must be specified in `args'.

3.15.8 setter
-------------

RTL expression to set the value of the operand.  All operands refered
to must be specified in `args'.  Use `newval' to refer to the value to
be set.

3.15.9 choices
--------------

For anyof operands, the names of the derived operands.  The operand may
be "any of" the specified choices.

   ---------- Footnotes ----------

   (1) A scalar instruction field is a simple ifield (not a multi or
derived ifield), or a multi-ifield consisting of only simple ifields.

   (2) Like all rtx, the full syntax is `(member [(options)]
[member-mode] ifield-name (number-list [(options)] [numlist-mode]
value1 [value2 ...]))', but `options' and `mode' are not really useful
here.  `member-mode' is `BI', since the result is a boolean value.


File: cgen.info,  Node: Instructions,  Next: Macro-instructions,  Prev: Derived operands,  Up: RTL

3.16 Instructions
=================

Each instruction in the instruction set has an entry in the description
file.  (1)

   Instructions must be uniquely named within an instruction set, but
different instruction sets (ISAs) may have instructions with the same
name.

   The syntax for defining an instruction is:

     (define-insn
       (name insn-name)
       (comment "description")
       (attrs attribute-list)
       (syntax "assembler syntax")
       (format (+ field-list))
       (ifield-assertion expression)
       (semantics expression)
       (timing timing-data)
     )

   The required elements are: `name', ???.

   Instructions specific to a particular cpu variant are denoted as
such with the MACH attribute.

   Possible additions for the future:

   * a field to describe a final constraint for determining a match

   * choosing the output from a set of choices

3.16.1 attrs
------------

A list of attributes, for which there are several predefined instruction
attributes:

`MACH'
     A bitset attribute used to specify which machines have this
     hardware element. Do not specify the MACH attribute if the value
     is for all machines.

     Usage: `(MACH mach1,mach2,...)'

     There must be no spaces in "`mach1,mach2,...'".

`UNCOND-CTI'
     The instruction is an unconditional "control transfer instruction".

     (*Note: This attribute is derived from the semantic code. However
     if the computed value is wrong (dunno if it ever will be) the
     value can be overridden by explicitly mentioning it.)

`COND-CTI'
     The instruction is an conditional "control transfer instruction".

     (*Note: This attribute is derived from the semantic code. However
     if the computed value is wrong (dunno if it ever will be) the
     value can be overridden by explicitly mentioning it.)

`SKIP-CTI'
     The instruction can cause one or more insns to be skipped. This is
     derived from the semantic code.

`DELAY-SLOT'
     The instruction has one or more delay slots. This is derived from
     the semantic code.

`RELAXABLE'
     The instruction has one or more identical variants.  The assembler
     tries this one first and then the relaxation phases switches to
     larger ones as necessary.

`RELAXED'
     The instruction is a non-minimal variant of a relaxable
     instruction.  It is avoided by the assembler in the first pass.

`ALIAS'
     Internal attribute set for macro-instructions that are an alias
     for one real insn.

`NO-DIS'
     For macro-instructions, don't use during disassembly.

3.16.2 syntax
-------------

This is a character string consisting of raw characters and operands.
Fields are denoted by `$operand' or `${operand}'.  The `${operand}'
form is required if the operand name contains non-alphanumeric
characters.  If a `$' is required in the syntax, it is specified with
`\$'.  If a `\' is required in the syntax, it is specified with `\\'.

   At most one white-space character may be present and it must be a
blank separating the instruction mnemonic from the operands.  This
doesn't restrict the user's assembler, this is just a description file
restriction to separate the mnemonic from the operands(2).  Note that
the assembler will accept multiple spaces in the assembler code after
the mnemonic and between operands as expected.

   Operands can refer to registers, constants, and whatever else is
necessary.

   Instruction mnemonics can take operands.  For example, on the SPARC a
branch instruction can take `,a' as an argument to indicate the
instruction is being annulled (e.g. `bge$a $disp22').

3.16.3 format
-------------

This is a complete list of fields that specify the instruction.  At
present it must be prefaced with `+' to allow for future additions.
Reserved bits must also be specified, gaps are not allowed.  The
ordering of the fields is not important.

   Format elements can be any of:

   * an instruction field name with an integer, e.g. `(f-op1 4)'

   * an instruction field name with an enum, e.g. `(f-op1 OP1_4)'

   * an instruction field enum, e.g. `OP1_4'

   * an operand name, e.g. `dr'

3.16.4 ifield-assertion
-----------------------

This is an expression with a boolean result that is run as the final
part of instruction decoding to verify a match.

   The syntax of the assertion is a restricted subset of RTL.  *Note
ifield-assertion-rtl::.

3.16.5 semantics
----------------

This field provides a mathematical description of what the instruction
does.  Its syntax is GCC RTL-like on purpose since GCC's RTL is well
known by the intended audience.  However, it is not intended that it be
precisely GCC RTL.

   Obviously there are some instructions that are difficult if not
impossible to provide a description for (e.g. I/O instructions).  Rather
than create a new semantic function for each quirky operation, escape
hatches to C are provided to handle all such cases.  The `c-code',
`c-call' and `c-raw-call' semantic functions provide an escape-hatch to
invoke C code to perform the operation. *Note Expressions::.

3.16.6 timing
-------------

A list of entries for each function unit the instruction uses on each
machine that supports the instruction.  The default function unit is
the u-exec unit.

   The syntax is:

     (model-name (unit name (direction unit-var-name1 insn-operand-name1)
                            (direction unit-var-name2 insn-operand-name2)
                            ...
                            (cycles cycle-count))

   direction/unit-var-name/insn-operand-name mappings are optional.
They map unit inputs/outputs to semantic elements.  The direction
specifier can be `in' or `out' mapping the name of a unit input or
output, respectively, to an insn operand.

   `cycles' overrides the `done' value (latency) of the function unit
and is optional.

3.16.7 Simplification macros
----------------------------

To simplify `.cpu' files several pmacros are provided.

   The `define-normal-insn' pmacro (with alias `dni') takes a fixed set
of positional arguments for the typical instruction.

   The syntax of `dni' is:

   `(dni name comment attrs syntax format semantics timing)'

   Example:

     (dni addi "add 8 bit signed immediate"
          ()
          "addi $dr,$simm8"
          (+ OP1_4 dr simm8)
          (set dr (add dr simm8))
          ()
     )

   ---------- Footnotes ----------

   (1) For complicated instruction sets this is a lot of typing.
However, macros can reduce a lot of that typing.  The real question is
given the amount of information that must be expressed, how succinct
can one express it and still be clean and usable?  I'm open to opinions
on how to improve this, but such improvements must take everything CGEN
wishes to be into account.  (*Note: Of course no claim is made that the
current design is the be-all and end-all or that there is one be-all
and end-all.)

   (2) The restriction can be relaxed by saying the first blank is the
one that separates the mnemonic from its operands.


File: cgen.info,  Node: Macro-instructions,  Next: Modes,  Prev: Instructions,  Up: RTL

3.17 Macro-instructions
=======================

Macro-instructions are for the assembler side of things and are not used
by the simulator.

   Macro-instructions must be uniquely named within an instruction set,
but different instruction sets (ISAs) may have macro-instructions with
the same name.

   The syntax for defining a macro-instruction is:

     (define-macro-insn
       (name macro-insn-name)
       (comment "description")
       (attrs attribute-list)
       (syntax "assembler syntax")
       (expansions expansion-spec)
     )

3.17.1 syntax
-------------

Syntax of the macro-instruction. This has the same value as the
`syntax' field in `define-insn'.

3.17.2 expansions
-----------------

An expression to emit code for the instruction.  This is intended to be
general in nature, allowing tests to be done at runtime that choose the
form of the expansion.  Currently the only supported form is:

   `(emit insn arg1 arg2 ...)'

   where `insn' is the name of an instruction defined with
`define-insn' and _argn_ is the set of operands to `insn''s syntax.
Each argument is mapped in order to one operand in `insn''s syntax and
may be any of:

   * operand specified in `syntax'

   * `(operand value)'

3.17.3 Simplification macros
----------------------------

To simplify `.cpu' files several pmacros are provided.

   The `define-normal-macro-insn') pmacro (with alias `dnmi') takes a
fixed set of positional arguments for the typical macro-instruction.

   The syntax of `dnmi' is:

   `(dnmi name comment attrs syntax expansion)'

   Example:

     (dni st-minus "st-" ()
          "st $src1,$src2"
          (+ OP1_2 OP2_7 src1 src2)
          (sequence ((WI new-src2))
     	       (set new-src2 (sub src2 (const 4)))
     	       (set (mem WI new-src2) src1)
     	       (set src2 new-src2))
          ()
     )

     (dnmi push "push" ()
       "push $src1"
       (emit st-minus src1 (src2 15)) ; "st %0,sp"
     )

   In this example, the `st-minus' instruction is a general
store-and-decrement instruction and `push' is a specialized version of
it that uses the stack pointer.


File: cgen.info,  Node: Modes,  Next: Expressions,  Prev: Macro-instructions,  Up: RTL

3.18 Modes
==========

Modes provide a simple and succinct way of specifying data types.

   (*Note: Should more complex types will be needed (e.g. structs?
unions?), these can be handled by extending the definition of a mode to
encompass them.)

   Modes are similar to their usage in GCC, but there are some
differences:

   * modes for boolean values (i.e. bits) are also supported as they are
     useful

   * integer modes exist in signed and unsigned versions

   * constants have modes

   Currently supported modes are:

`VOID'
     VOIDmode in GCC.

`DFLT'
     Indicate the default mode is wanted, the value of which depends on
     context.  This is a pseudo-mode and never appears in generated
     code.

`BI'
     Boolean zero/one

`QI,HI,SI,DI'
     Same as GCC.

     QI is an 8 bit quantity ("quarter int").  HI is a 16 bit quantity
     ("half int").  SI is a 32 bit quantity ("single int").  DI is a 64
     bit quantity ("double int").

     In cases where signedness matters, these modes are signed.

`UQI,UHI,USI,UDI'
     Unsigned versions of QI,HI,SI,DI.

     These modes do not appear in semantic RTL.  Instead, the RTL
     function specifies the signedness of its operands where necessary.
     To a cpu, a 32 bit register is a 32 bit register.  Ditto for when
     the 32 bit quantity lives in memory.  It's only in how it is
     subsequently used or interpreted that signedness might come into
     play.  When signedness comes into play on the chip, it's explicitly
     specified in the operation, _not_ in the data.  Ergo from this
     perspective Umodes don't belong in .cpu files.  This is the
     perspective to use when writing .cpu files.

`WI,UWI'
     word int, unsigned word int (word_mode in gcc).  These are aliases
     for the real mode, typically either `SI' or `DI'.

`SF,DF,XF,TF'
     Same as GCC.

     SF is a 32 bit IEEE float ("single float").  DF is a 64 bit IEEE
     float ("double float").  XF is either an 80 or 96 bit IEEE float
     ("extended float").  (*Note: XF values on m68k and i386 are
     different so may wish to give them different names).  TF is a 128
     bit IEEE float.

`AI'
     Address integer

`IAI'
     Instruction address integer

`INT,UINT'
     Varying width int/unsigned-int.  The width is specified by context,
     usually in an instruction field definition.



File: cgen.info,  Node: Expressions,  Next: Macro-expressions,  Prev: Modes,  Up: RTL

3.19 Expressions
================

The syntax of CGEN's RTL expressions (or _rtx_) basically follows that
of GCC's RTL.

   The handling of modes is different to simplify the implementation.
Implementation shouldn't necessarily drive design, but it was a useful
simplification.  Still, it needs to be reviewed.  The difference is that
in GCC `(function:MODE arg1 ...)' is written in CGEN as `(function MODE
arg1 ...)'.  Note the space after `function'.

   GCC RTL allows flags to be recorded with RTL (e.g. MEM_VOLATILE_P).
This is supported in CGEN RTL by prefixing each RTL function's arguments
with an optional list of modifiers: `(function (#:mod1 #:mod2) MODE
arg1 ...)'.  The list is a set of modifier names prefixed with '#:'.
They can take arguments.  ??? Modifiers are supported by the RTL
traversing code, but no use is made of them yet.

   The mode may be elided if it can be deduced from the operands.  For
example, while the full form of `add' is `(add () MODE arg1 arg2)', it
may be written as `(add arg1 arg2)', with the mode being taken from the
mode of `arg1'.  The fully specified version is called the "canonical"
form.

   The currently defined semantic functions are:

`(set mode destination source)'
     Assign `source' to `destination' reference in mode `mode'.

`(set-quiet mode destination source)'
     Assign `source' to `destination' referenced in mode `mode', but do
     not print any tracing message.

`(reg mode hw-name [index])'
     Return an `operand' of hardware element `hw-name' in mode `mode'.
     If `hw-name' is an array, `index' selects which register.

`(raw-reg mode hw-name [index])'
     Return an `operand' of hardware element `hw-name' in mode `mode',
     bypassing any `get' or `set' specs of the register.  If `hw-name'
     is an array, `index' selects which register.  This cannot be used
     with virtual registers (those specified with the `VIRTUAL'
     attribute).

     `raw-reg' is most often used in `get' and `set' specs of a
     register: if it weren't read and write operations would infinitely
     recurse.

`(mem mode address)'
     Return an `operand' of memory referenced at `address' in mode
     `mode'.

`(const mode value)'
     Return an `operand' of constant `value' in mode `mode'.

`(enum mode value-name)'
     Return an `operand' of constant `value-name' in mode `mode'.  The
     value must be from a previously defined enum.

`(subword mode value word-num)'
     Return part of `value'.  Which part is determined by `mode' and
     `word-num'.  There are three cases.

     If `mode' is the same size as the mode of `value', `word-num' must
     be `0' and the result is `value' recast in the new mode.  There is
     no change in the bits of `value', they're just interpreted in a
     possibly different mode.  This is most often used to interpret an
     integer value as a float and vice versa.

     If `mode' is smaller than the mode of `value', `value' is divided
     into N pieces and `word-num' picks which piece.  All pieces have
     the size of `mode' except possibly the last.  If the last piece
     has a different size, it cannot be referenced.  Word number 0 is
     the most significant word, regardless of endianness.

     If `mode' is larger than the mode of `value', `value' is
     interpreted in the larger mode with the upper most significant
     bits treated as garbage (their value is assumed to be unimportant
     to the context in which the value will be used).  `word-num' must
     be `0'.

`(join out-mode in-mode arg1 . arg-rest)'
     Concatenate `arg1[,arg2[,...]]' to create a value of mode
     `out-mode'.  `arg1' becomes the most significant part of the
     result.  Each argument is interpreted in mode `in-mode'.
     `in-mode' must evenly divide `out-mode'.

`(sequence mode ((mode1 local1) ...) expr1 ...)'
     Execute `expr1', `expr2', etc. sequentially.  At least one
     expression must be specified, even if the result mode is `VOID'.

     The result, if non-void-mode, is the value of the last expression.

     `mode' is the mode of the result.  If `mode' is elided it is set
     to `VOID' (void mode).

     ``((mode1 local1) ...)'' is a set of local variables.

`(parallel mode empty expr1 ...)'
     Execute `expr1', `expr2', etc. in parallel. All inputs are read
     before any output is written.  At least one expression must be
     specified.

     `empty' must be `()' and is present for consistency with
     `sequence'.

     `mode' must be `VOID' (void mode), or it can be elided.

`(do-count mode iteration-variable number-of-iterations expr1 ...)'
     This is a simple looping operation.  Execute `expr1', `expr2',
     etc. the specified number of times.  At least one expression must
     be specified.

     `iteration-variable' will contain the iteration number and is
     available for use in expressions.  It has mode `INT'.  It's value
     will be 0 ... `number-of-iterations' - 1.

     `number-of-iterations' is an rtl expression of mode INT (or a
     compatible mode).  It is computed once and may not be modified
     inside the loop.

     `mode' must be `VOID' (void mode), or it can be elided.

`(unop mode operand)'
     Perform a unary arithmetic operation.

     `unop' is one of `neg', `abs', `inv', `not', `zflag', `nflag'.
     `zflag' returns a bit indicating if `operand' is zero. `nflag'
     returns a bit indicating if `operand' is negative. `inv' returns
     the bitwise complement of `operand', whereas `not' returns its
     logical negation.

`(binop mode operand1 operand2)'
     Perform a binary arithmetic operation.

     `binop' is one of `add', `sub', `and', `or', `xor', `mul', `div',
     `udiv', `mod', `umod'.

`(binop-with-bit mode operand1 operand2 operand3)'
     Same as `binop', except taking 3 operands. The third operand is
     always a single bit.

     `binop-with-bit' is one of `addc', `addc-cflag', `addc-oflag',
     `subc', `subc-cflag', `subc-oflag'.

     Note: The following are deprecated:

        * `add-cflag', replaced with `addc-cflag'

        * `add-oflag', replaced with `addc-oflag'

        * `sub-cflag', replaced with `subc-cflag'

        * `sub-cflag', replaced with `subc-oflag'

`(shiftop mode operand1 operand2)'
     Perform a shift operation.  `operand1' is shifted (or rotated) by
     the amount specified in `operand2'.

     `shiftop' is one of `sll', `srl', `sra', `ror', `rol'.

     `mode' must match the mode of `operand1'.  The mode of `operand1'
     may be any integral mode.  The mode of `operand2' may be any
     integral mode, and need not match the mode of `operand1'.

     It is an error if `operand2' is negative or greater than or equal
     to the size of `operand1'.  If the architecture handles negative
     or large shift amounts, that needs to be handled in the
     surrounding RTL.

`(andif mode operand1 operand2)'
     Evaluate `operand1'.  If it evaluates to zero the result is zero,
     and `operand2' is not evaluated.  If `operand1' evaluates to
     non-zero, then evaluate `operand2'.  If it evaluates to non-zero
     the result is one, otherwise the result is zero.

     The mode of the result is `BI'.  `mode' is generally elided or is
     `BI'.

`(orif mode operand1 operand2)'
     Evaluate `operand1'.  If it evaluates to non-zero the result is
     one, and `operand2' is not evaluated.  If `operand1' evaluates to
     zero, then evaluate `operand2'.  If it evaluates to non-zero the
     result is one, otherwise the result is zero.

     The mode of the result is `BI'.  `mode' is generally elided or is
     `BI'.

`(integer-convop mode operand)'
     Perform an integer mode->mode conversion operation.

     `integer-convop' is one of:

        * `ext' Sign-extend `operand', which must have an integer mode
          narrower than `mode', which also must be an integer mode.

        * `zext' Zero-extend `operand', which must have an integer mode
          narrower than `mode', which also must be an integer mode.

        * `trunc' Truncate `operand', which must have an integer mode
          wider than `mode', which also must be an integer mode.

`(float-convop mode how operand)'
     Perform a mode->mode conversion operation involving a floating
     point value.

     Conversions involving floating point values need to specify how
     things like truncation will be performed, e.g., the rounding mode.
     `how' is an rtx of mode `INT' that specifies how the conversion
     will be performed.  The interpretation of `how' is
     architecture-dependent, except that a value of zero has a specific
     meaning: If a particular floating-point conversion can only be
     done one way, or if the conversion is to be done the "default"
     way, specify zero for `how'.  What "the default way" is is
     application-dependent.

     `float-convop' is one of:

        * `fext' Extend `operand', which must have a floating point mode
          narrower than `mode', which also must be a floating point
          mode.

        * `ftrunc' Truncate `operand', which must have a floating point
          mode wider than `mode', which also must be a floating point
          mode.

        * `float' Convert `operand', which must have an integer mode,
          to a floating point value of mode `mode'.  `operand' is
          treated as a signed integer.

        * `ufloat' Convert `operand', which must have an integer mode,
          to a floating point value of mode `mode'.  `operand' is
          treated as an unsigned integer.

        * `fix' Convert `operand', which must have a floating point
          mode, to a signed integer of mode `mode'.

        * `ufix' Convert `operand', which must have a floating point
          mode, to an unsigned integer of mode `mode'.

     An enum is defined that specifies several predefined rounding
     modes.

          (define-enum
            (name fpconv-kind)
            (comment "builtin floating point conversion kinds")
            (attrs VIRTUAL) ;; let app provide def'n instead of each cpu's desc.h
            (prefix FPCONV-)
            (values ((DEFAULT 0)
                     (TIES-TO-EVEN 1)
                     (TIES-TO-AWAY 2)
                     (TOWARD-ZERO 3)
                     (TOWARD-POSITIVE 4)
                     (TOWARD-NEGATIVE 5)))
          )

`(cmpop mode operand1 operand2)'
     Perform a comparison.

     `cmpop' is one of `eq', `ne', `lt', `le', `gt', `ge', `ltu', `leu',
     `gtu', `geu'.

     If the comparison succeeds the result is one, otherwise the result
     is zero.  The mode of the result is `BI'.

`(mathop mode operand)'
     Perform a mathematical operation.

     `mathop' is one of `sqrt', `cos', `sin'.

`(*nan mode operand)'
     Return a boolean indicating if `operand' is a NaN.  `mode' must be
     a floating point mode.  There are three versions.

        * (nan operand) Test whether `operand' is any kind of NaN.

        * (qnan operand) Test whether `operand' is a quiet NaN.

        * (snan operand) Test whether `operand' is a signalling NaN.

`(if mode condition then [else])'
     Standard `if' statement.

     `condition' is any arithmetic expression.  If the value is
     non-zero the `then' part is executed.  Otherwise, the `else' part
     is executed (if present).

     `mode' is the mode of the result, not of `condition'.  If `mode'
     is not `VOID' (void mode), `else' must be present.  When the
     result is used, `mode' must specified, and not be `VOID'.

`(cond mode (condition1 expr1a ...) (...) [(else exprNa...)])'
     From Scheme: keep testing conditions until one succeeds, and then
     process the associated expressions.

`(case mode test ((case1 ..) expr1a ..) (..) [(else exprNa ..)])'
     From Scheme: Compare `test' with `case1', `case2', etc. and
     process the associated expressions.

`(c-code mode "C expression")'
     An escape hook to insert arbitrary C code. `mode' must the
     compatible with the result of "C expression".

`(c-call mode symbol operand1 operand2 ...)'
     An escape hook to emit a subroutine call to function named `symbol'
     passing operands `operand1', `operand2', etc.  An implicit first
     argument of `current_cpu' is passed to `symbol'.  `mode' is the
     mode of the result.  Be aware that `symbol' will be restricted by
     reserved words in the C programming language and by existing
     symbols in the generated code.

`(c-raw-call mode symbol operand1 operand2 ...)'
     Same as `c-call': except there is no implicit `current_cpu' first
     argument.  `mode' is the mode of the result.

`(clobber mode object)'
     Indicate that `object' is written in mode `mode', without saying
     how. This could be useful in conjunction with the C escape hooks.

`(delay mode num expr)'
     Indicate that there are `num' delay slots in the processing of
     `expr'.  When using this rtx in instruction semantics, CGEN will
     infer that the instruction has the DELAY-SLOT attribute.

`(delay num expr)'
     In older "sim" simulators, indicates that there are `num' delay
     slots in the processing of `expr'. When using this rtx in
     instruction semantics, CGEN will infer that the instruction has
     the DELAY-SLOT attribute.

     In newer "sid" simulators, evaluates to the writeback queue for
     hardware operand `expr', at `num' instruction cycles in the
     future. `expr' _must_ be a hardware operand in this case.

     For example, `(set (delay 3 pc) (+ pc 1))' will schedule write to
     the `pc' register in the writeback phase of the 3rd instruction
     after the current. Alternatively, `(set gr1 (delay 3 gr2))' will
     immediately update the `gr1' register with the _latest write_ to
     the `gr2' register scheduled between the present and 3
     instructions in the future. `(delay 0 ...)'  refers to the
     writeback phase of the current instruction.

     This effect is modeled with a circular buffer of "write stacks"
     for each hardware element (register banks get a single stack). The
     size of the circular buffer is calculated from the uses of `(delay
     ...)' rtxs. When a delayed write occurs, the simulator pushes the
     write onto the appropriate write stack in the "future" of the
     circular buffer for the written-to hardware element. At the end of
     each instruction cycle, the simulator executes all writes in all
     write stacks for the time slice just ending. When a delayed read
     (essentially a pipeline bypass) occurs, the simulator looks ahead
     in the circular buffer for any writes scheduled in the future
     write stack. If it doesn't find one, it progressively backs off
     towards the "current" instruction cycle's write stack, and if it
     still finds no scheduled writes then it returns the current state
     of the CPU. Thus while delayed writes are fast, delayed reads are
     potentially slower in a simulator with long pipelines and very
     large register banks.

`(annul yes?)'
     Annul the following instruction if `yes?' is non-zero. This rtx is
     an experiment and will probably change.

`(skip yes?)'
     Skip the next instruction if `yes?' is non-zero. This rtx is an
     experiment and will probably change.

`(symbol name)'
     Return a symbol with value `name', for use in attribute
     processing. This is equivalent to `quote' in Scheme but `quote'
     sounds too jargonish.

`(int-attr mode object attr-name)'
     Return the value of attribute `attr-name' in mode `mode'.
     `object' must currently be `(current-insn)', the current
     instruction, or `(current-mach)', the current machine.  The
     attribute's value must be representable as an integer.

`(eq-attr mode object attr-name value)'
     Return non-zero if the value of attribute `attr-name' of object
     `object' is `value'.

     _NOTE:_ List values of `value' may be changed to allow use the
     `number-list' rtx function.  If `value' is a list return "true" if
     the attribute is any of the listed values.  But this is not
     implemented yet.

`(index-of operand)'
     Return the index of `operand'. For registers this is the register
     number.

`(regno operand)'
     Same as `index-of', but improves readability for registers.

`(error mode message)'
     Emit an error message from CGEN RTL. Error message is specified by
     `message'.

`(nop)'
     A no-op.

`(ifield field-name)'
     Return the value of field `field-name'. `field-name' must be a
     field in the instruction.


   Operands can be any of:

   * an operand defined in the description file

   * a register reference, created with (reg mode [index])

   * a memory reference, created with (mem mode address)

   * a constant, created with (const mode value)

   * a `sequence' local variable

   * a `do-count' iteration variable

   * another expression

   The `symbol' in a `c-call' or `c-raw-call' function is currently the
name of a C function or macro that is invoked by the generated semantic
code.


File: cgen.info,  Node: Macro-expressions,  Prev: Expressions,  Up: RTL

3.20 Macro-expressions
======================

Macro RTL expressions are a way to not have to always specify a mode
for every expression (and sub-expression thereof).  Whereas the formal
way to specify, say, an add is `(add SI arg1 arg2)' if SI is the
default mode of `arg1' then this can be simply written as `(add arg1
arg2)'.  This gets expanded to `(add DFLT arg1 arg2)' where `DFLT'
means "default mode".

   It might be possible to replace macro expressions with preprocessor
macros, however for the nonce there is no plan to do this.


File: cgen.info,  Node: Preprocessor macros,  Next: Porting,  Prev: RTL,  Up: Top

4 Preprocessor macros
*********************

Preprocessor macros provide a way of simplifying the writing of `.cpu'
files.

* Menu:

* Pmacros introduction::   Introduction to pmacros
* Defining pmacros::       `define-pmacro'
* Using pmacros::          Using preprocessor macros
* Pmacro expansion::       How pmacros are expanded
* Syntactic forms::        Pmacros that defer argument expansion
* Default argument values::  Specifying default values of arguments
* Multiple result statements::  Using `begin'
* Symbols and strings::    Symbols and strings
* Number utilities::       Manipulating numbers
* List utilities::         Manipulating lists
* Iteration utilities::    Iterating over lists
* Conditional macros::     Conditional execution
* Pmacro utilities::       Utilities for using macros
* Debugging utilities::    Pmacros to assist debugging
* Comparisons::            Comparing things
* Arithmetic functions::   Math
* Logical functions::      Shifts, bitwise logical functions
* Internal use pmacros::   For internal use only


File: cgen.info,  Node: Pmacros introduction,  Next: Defining pmacros,  Up: Preprocessor macros

4.1 Pmacros introduction
========================

The macro facility provided by CGEN is quite extensive.  This is to
give `.cpu' file writers the freedom to write the file in ways that
work for the architecture in question.  Not all architectures are best
described in the same way.

   The macros are called `pmacros' because the word `macro' has become
overloaded.  For clarity, we give them a unique name: `pmacros'.

   One important point to keep in mind regarding pmacros is that when
loading `.cpu' files all pmacros are expanded and discarded, their only
purpose is to simplify writing the `dni's and other elements of the
architecture description.

   Therefore, do not try to write RTL as pmacros.  You can of course
use pmacros to assist in the writing of RTL, but remember that the
resulting RTL _cannot_ use pmacros.  By the time the RTL is processed
all pmacros have been expanded and discarded.

   A simple picture may help.  Here is a basic diagram of the steps in
processing cpu descriptions.

              (1) .cpu file
                     |
           (2) pmacro expansion
                     |
     (3) define-{insn,operand,etc.} processing
                     |
        (4) instruction set analysis
                     |
      (5) application source file generation

   Once CGEN gets to step (3) pmacros no longer exist.


File: cgen.info,  Node: Defining pmacros,  Next: Using pmacros,  Prev: Pmacros introduction,  Up: Preprocessor macros

4.2 Defining pmacros
====================

There are two kinds of macros:

   * function macros

   * variable macros

   Preprocessor function macros are defined with:

     (define-pmacro (name [parm1 parm2 ... parmN])
       ["optional comment"]
       expansion
     )

   `expansion' must be exactly one expression.

   Preprocessor variable macros are just global variables, nothing
special.  When invoked their value is used in place of their name.

   Variable macros are defined with:

     (define-pmacro name
       ["optional comment"]
       expansion
     )


File: cgen.info,  Node: Using pmacros,  Next: Pmacro expansion,  Prev: Defining pmacros,  Up: Preprocessor macros

4.3 Using pmacros
=================

Functional macros are invoked in either of two ways: positional
arguments or specifying arguments by name.

     (define-pmacro (foo arg1 arg2) (bar arg1 arg2))

     ;; Invoke by positional arguments.

     (foo abc def) ==> (bar abc def)

     ;; Invoke by naming arguments.

     (foo #:arg1 ghi #:arg2 jkl) ==> (bar ghi jkl)

   Variable macros are invoked simply by specifying their name.

     (define-pmacro foo "abc")

     (.str foo "def") ==> "abcdef"


File: cgen.info,  Node: Pmacro expansion,  Next: Syntactic forms,  Prev: Using pmacros,  Up: Preprocessor macros

4.4 Pmacro expansion
====================

Most(1) function pmacros are expanded by first processing any macros in
the invocation, binding the resulting expressions to the pmacro's
parameters, processing the pmacro according to its definition, and
returning the result.  Free variables are left unchanged.(2)

   Variable macros are expanded simply by replacing their name with
their value.

   After a pmacro has been expanded, if the result is a symbol that
names another pmacro, it is in turn processed.  This happens just once,
not repeatedly.(3)

   Here is a simple example that uses pmacros to simplify the
definition of several instructions.

     ;; OP1_*,OP2_* are previously defined enums
     (define-pmacro arithmetic-insns
       ((add OP2_0) (sub OP2_1) (mul OP2_2) (div OP2_3))
     )
     (define-pmacro (make-arith-reg/reg-format opcode)
       (+ OP1_0 opcode dr sr)
     )
     (define-pmacro (make-arith-reg/imm-format opcode)
       (+ OP1_1 opcode dr sr)
     )
     (define-pmacro (define-arith-insn ispec)
       (begin
         (dni (.ref ispec 0)
              (.str (.ref ispec 0) " reg/reg")
              ()
              (.str (.ref ispec 0) " $dr,$sr")
              (make-arith-reg/reg-format (.ref ispec 1))
              (set dr ((.ref ispec 0) dr sr))
              ()
              )
         (dni (.ref ispec 0)
              (.str (.ref ispec 0) " reg/imm")
              ()
              (.str (.ref ispec 0) " $dr,$imm")
              (make-arith-reg/imm-format (.ref ispec 1))
              (set dr ((.ref ispec 0) dr imm))
              ()
              )
       )
     )

     ;; Create dnis for each kind of instruction.
     ;; The result of this is:
     ;; (begin (begin (dni ...) ...) (begin (dni ...) ...) ...)
     (.splice begin (.unsplice (.map define-arith-insn arithmetic-insns)))

   The `.splice', `.unsplice' are necessary to pass properly formed
expressions to the `.cpu' file reader.  If we just used `(.map
define-arith-insn arithmetic-insns)' the reader would see `((begin (dni
...) ...) (begin (dni ...) ...))'.  Note how the first `begin' is
nested within a list, and does not appear in the "top level" list.

   Another way to accomplish the same thing that doesn't require
`.splice', `.unsplice' is to use `.for-each', `.exec'.  `.for-each' is
only used for its side-effects, it does not return a result.
Therefore, in order to actually cause the `.cpu' file reader to see any
definitions we need to use `.exec' to pass the dnis to the reader.

     (define-pmacro (define-arith-insn ispec)
       (.exec (dni (.ref ispec 0)
                (.str (.ref ispec 0) " reg/reg")
                ()
                (.str (.ref ispec 0) " $dr,$sr")
                (make-arith-reg/reg-format (.ref ispec 1))
                (set dr ((.ref ispec 0) dr sr))
                ()
                ))
       (.exec (dni (.ref ispec 0)
                (.str (.ref ispec 0) " reg/imm")
                ()
                (.str (.ref ispec 0) " $dr,$imm")
                (make-arith-reg/imm-format (.ref ispec 1))
                (set dr ((.ref ispec 0) dr imm))
                ()
                ))
     )
     (.for-each define-arith-insn arithmetic-insns)

   ---------- Footnotes ----------

   (1) Syntactic form pmacros don't pre-evaluate their arguments.
*Note Syntactic forms::.

   (2) A "free variable", as defined here, is one that is not already
bound, be it to parameter, macro, or local variable within a macro.
Note that to pmacros, cpu description file elements like `reg',
`sequence', `VOID', etc. are just symbols; they have no special meaning.

   (3) This behaviour will go away eventually, do not rely on it.


File: cgen.info,  Node: Syntactic forms,  Next: Default argument values,  Prev: Pmacro expansion,  Up: Preprocessor macros

4.5 Syntactic forms
===================

Some function pmacros are called `syntactic forms'.  These pmacros are
processed differently in that parameters are _not_ evaluated first.
Instead it is up to the pmacro to decide when, and if, the parameters
are evaluated.

   The syntactic forms are:

   * `.pmacro'.  *Note Defining a pmacro inline::.

   * `.let', `.let*'.  *Note Defining a block of locals::.

   * `.if'.  *Note Traditional `if'::.

   * `.case'.  *Note Traditional `case'::.

   * `.cond'.  *Note Extended if/elseif/else::.

   * `.begin'.  *Note A block of statements::.

   * `.andif'.  *Note .andif::.

   * `.orif'.  *Note .orif::.


   The docs for each syntactic pmacro describes when it evaluates its
arguments.

   All syntactic form pmacros are pre-defined.  The user can not
currently define his/her own.


File: cgen.info,  Node: Default argument values,  Next: Multiple result statements,  Prev: Syntactic forms,  Up: Preprocessor macros

4.6 Default argument values
===========================

Invoking pmacros by specifying argument names allows some, or all,
arguments to be elided and thus allows for arguments to have default
values.

   Specify default values with the following syntax.

     (define-pmacro (macro-name (arg1 . default-value)
                                (arg2 . default value) ...)
       ...
     )

   To invoke a pmacro with default values for some, or all, arguments,
you _must_ specify arguments by name.

   Example:

     (define-pmacro (foo (arg1 . 1) (arg2 . 2))
       (bar arg1 arg2)
     )

     (foo #:arg1 4) ==> (bar 4 2)

     (foo 4) ==> ERROR, must invoke pmacro by specifying arguments by name


File: cgen.info,  Node: Multiple result statements,  Next: Symbols and strings,  Prev: Default argument values,  Up: Preprocessor macros

4.7 Multiple result statements
==============================

The result of a preprocessor macro is exactly one expression.  It is
often useful, however, to return multiple expressions, say for example
when you want one macro to define several instructions.

   The way to do this is to enclose all the expressions with `begin'.
`begin' is only valid at the top [definition] level.

   Note that this is _not_ the `.begin' builtin pmacro.  We want to
pass a list of statements to the `.cpu' file reader, and pmacros have
all been evaluated and discarded by this point.


File: cgen.info,  Node: Symbols and strings,  Next: Number utilities,  Prev: Multiple result statements,  Up: Preprocessor macros

4.8 Symbols and strings
=======================

There are several builtin macros for symbol and string manipulation.

* Menu:

* Symbol concatenation::          The `.sym' builtin
* String concatenation::          The `.str' builtin
* Convert a number to a hex::     The `.hex' builtin
* Convert a string to uppercase:: The `.upcase' builtin
* Convert a string to lowercase:: The `.downcase' builtin
* Getting part of a string::      The `.substring' builtin
* Symbol or string length::       The `.length' builtin


File: cgen.info,  Node: Symbol concatenation,  Next: String concatenation,  Up: Symbols and strings

4.8.1 Symbol concatenation
--------------------------

Symbol and string concatenation are supported. Symbol concatenation is
done with:

   `(.sym arg1 arg2 ...)'

   Acceptable arguments are symbols, strings, and numbers.  The result
is a symbol with the arguments concatenated together.  Numbers are
converted to a string, base 10, and then to a symbol.  The result must
be a valid Scheme symbol with the additional restriction that the first
character must be a letter.  The resulting symbol is recursively
macro-expanded.


File: cgen.info,  Node: String concatenation,  Next: Convert a number to a hex,  Prev: Symbol concatenation,  Up: Symbols and strings

4.8.2 String concatenation
--------------------------

String concatenation is done with

   `(.str arg1 arg2 ...)'

   Acceptable arguments are symbols, strings, and numbers.  The result
is a string with the arguments concatenated together.  Numbers are
converted base 10.

   Example:

     (define-pmacro (bin-op mnemonic op2-op sem-op)
       (dni mnemonic
            (.str mnemonic " reg/reg")
            ()
            (.str mnemonic " $dr,$sr")
            (+ OP1_0 op2-op dr sr)
            (set dr (sem-op dr sr))
            ())
     )
     (bin-op and OP2_12 and)
     (bin-op or OP2_14 or)
     (bin-op xor OP2_13 xor)


File: cgen.info,  Node: Convert a number to a hex,  Next: Convert a string to uppercase,  Prev: String concatenation,  Up: Symbols and strings

4.8.3 Convert a number to a hex
-------------------------------

Convert a number to a lowercase hex string with `.hex'.  If `width' is
present, the result is that many characters beginning with the least
significant digit.  Zeros are prepended as necessary.

   Syntax: `(.hex number [width])'

   Examples:

     (.hex 42)   --> "2a"
     (.hex 42 1) --> "a"
     (.hex 42 4) --> "002a"


File: cgen.info,  Node: Convert a string to uppercase,  Next: Convert a string to lowercase,  Prev: Convert a number to a hex,  Up: Symbols and strings

4.8.4 Convert a string to uppercase
-----------------------------------

Convert a string to uppercase with `.upcase'.

   Syntax: `(.upcase string)'

   Example:

     (.upcase "foo!") --> "FOO!"


File: cgen.info,  Node: Convert a string to lowercase,  Next: Getting part of a string,  Prev: Convert a string to uppercase,  Up: Symbols and strings

4.8.5 Convert a string to lowercase
-----------------------------------

Convert a string to lowercase with `.downcase'.

   Syntax: `(.downcase string)'

   Example:

     (.downcase "BAR?") --> "bar?"


File: cgen.info,  Node: Getting part of a string,  Next: Symbol or string length,  Prev: Convert a string to lowercase,  Up: Symbols and strings

4.8.6 Getting part of a string
------------------------------

Extract a part of a string with `.substring'.

   Syntax: `(.substring string start end)'

   where `start' is the starting character, and `end' is one past the
ending character.  Character numbering begins at position 0.  If
`start' and `end' are the same, and both valid, the empty string is
returned.

   Example:

     (.substring "howzitgoineh?" 2 6) --> "wzit"


File: cgen.info,  Node: Symbol or string length,  Prev: Getting part of a string,  Up: Symbols and strings

4.8.7 Symbol or string length
-----------------------------

Compute the length, in characters, of a symbol or string.

   Syntax: `(.length symbol-or-string)'

   Examples:

     (.length abc) --> 3
     (.length "def") --> 3
     (.length "") --> 0


File: cgen.info,  Node: Number utilities,  Next: List utilities,  Prev: Symbols and strings,  Up: Preprocessor macros

4.9 Number utilities
====================

Builtin macros for manipulating numbers.

* Menu:

* Number generation::             The `.iota' builtin


File: cgen.info,  Node: Number generation,  Up: Number utilities

4.9.1 Number generation
-----------------------

Machine descriptions often require a list of sequential numbers.
Generate a list of numbers with the `.iota' builtin macro.

   Syntax: `(.iota count [start [incr]])'.

   Examples:

     (.iota 5)      --> 0 1 2 3 4
     (.iota 5 4)    --> 4 5 6 7 8
     (.iota 5 5 -1) --> 5 4 3 2 1


File: cgen.info,  Node: List utilities,  Next: Iteration utilities,  Prev: Number utilities,  Up: Preprocessor macros

4.10 List utilities
===================

Builtin macros for maninpulating lists.

* Menu:

* Creating lists::                The `.list' builtin
* List splicing::                 The `.splice' builtin
* Referencing a list element::    The `.ref' builtin
* List length::                   The `.length' builtin
* Lists of repeated elements::    The `.replicate' builtin
* Finding a subset of a list::    The `.find' builtin
* car/cdr::                       car, cdr, etc. from Scheme/Lisp


File: cgen.info,  Node: Creating lists,  Next: List splicing,  Up: List utilities

4.10.1 Creating lists
---------------------

Lists can be created with the `.list' builtin.

   Syntax: `(.list elm1 elm2 ...)'

   It's somewhat redundant as lists can also be created simply writing
`(elm1 elm2 ...)'.


File: cgen.info,  Node: List splicing,  Next: Referencing a list element,  Prev: Creating lists,  Up: List utilities

4.10.2 List splicing
--------------------

Syntax: `(.splice [expr1] [expr2] [(.unsplice list1)]
[(.unsplice list2)] [expr3] ...)'

   It is often useful to splice a list into a "parent" list.  This is
best explained with an example.

     (define-pmacro (splice-test a b c)
                    (.splice a (.unsplice b) c))
     (pmacro-dump (splice-test 1 (2) 3))

     --> (1 2 3)

   Note that a level of parentheses around `2' has been removed.

   This is useful, for example, when one wants to pass a list of fields
to a macro that defines an instruction.  For example:

     (define-pmacro (cond-move-1 name comment mnemonic cc-prefix cc-name cc-opcode
     			    src-name src-opcode cond test)
       (dni name
            (.str "move %" cc-name " " comment ", v9 page 191")
            ((MACH64))
            (.str mnemonic " " cc-prefix cc-name ",$" src-name ",$rd")
            (.splice + OP_2 rd OP3_MOVCC cond
     		(.unsplice cc-opcode) (.unsplice src-opcode))
            (if (test cc-name)
     	   (set rd src-name))
            ())
     )

   This macro, taken from `sparc64.cpu', defines a conditional move
instruction. Arguments `cc-opcode' and `src-opcode' are lists of
fields. The macro is invoked with (simplified from `sparc64.cpu'):

     (cond-move-1 mova-icc "blah ..." mova
                  "%" icc ((f-fmt4-cc2 1) (f-fmt4-cc1-0 0))
                  rs2 ((f-i 0) (f-fmt4-res10-6 0) rs2)
                  CC_A test-always)
     (cond-move-1 mova-imm-icc "blah ..." mova
                  "%" icc ((f-fmt4-cc2 1) (f-fmt4-cc1-0 0))
                  simm11 ((f-i 1) simm11)
                  CC_A test-always)

   Macro `cond-move-1' is being used here to define both the register
and the immediate value case.  Each case has a slightly different list
of opcode fields.  Without the use of `.splice'/`.unsplice', the
resulting formats would be:

     (+ OP_2 rd OP3_MOVCC CC_A ((f-fmt4-cc2-1) (f-fmt4-cc1-0 0))
        ((f-i 0) (f-fmt4-res10-6 0) rs2))

     and

     (+ OP_2 rd OP3_MOVCC CC_A ((f-fmt4-cc2-1) (f-fmt4-cc1-0 0))
        ((f-i 1) simm11))

   respectively.  This is not what is wanted.  What is wanted is

     (+ OP_2 rd OP3_MOVCC CC_A (f-fmt4-cc2-1) (f-fmt4-cc1-0 0)
        (f-i 0) (f-fmt4-res10-6 0) rs2)

     and

     (+ OP_2 rd OP3_MOVCC CC_A (f-fmt4-cc2-1) (f-fmt4-cc1-0 0)
        (f-i 1) simm11)

   respectively, which is what `.splice' achieves.

   `.unsplice' is a special reserved symbol that is only recognized
inside `.splice'.  There can be any number of `.unsplice' expressions
in a `.splice' but they all must be at the "top level".

   I.e. this is not supported: `(.splice 1 (2 3 (.unsplice (4 5))))'.

   Note that `.splice' without any `.unsplice' expressions behaves
identically to `.list'.

   Also note that the arguments to `.splice' and `.unsplice' are
evaluted first.  Any macro invocations are first expanded, and then
`.unsplice' is processed.


File: cgen.info,  Node: Referencing a list element,  Next: List length,  Prev: List splicing,  Up: List utilities

4.10.3 Referencing a list element
---------------------------------

Reference elements of a list with `.ref'.

   Syntax: `(.ref list element-number)'

   Example:

     (.ref (1 2 3) 1) --> 2


File: cgen.info,  Node: List length,  Next: Lists of repeated elements,  Prev: Referencing a list element,  Up: List utilities

4.10.4 List length
------------------

The length of a list is computed with `.length'.

   Syntax: `(.length list)'.

   Example:

     (.length (1 2 3)) --> 3


File: cgen.info,  Node: Lists of repeated elements,  Next: Finding a subset of a list,  Prev: List length,  Up: List utilities

4.10.5 Lists of repeated elements
---------------------------------

Create a list of repeated elements with `.replicate'.

   Syntax: `(.replicate n expr)'

   Example:

     (.replicate 4 5) --> (5 5 5 5)


File: cgen.info,  Node: Finding a subset of a list,  Next: car/cdr,  Prev: Lists of repeated elements,  Up: List utilities

4.10.6 Finding a subset of a list
---------------------------------

Compute a subset of a list matching a specified predicate with `.find'.

   Syntax: `(.find predicate list)'

   Example:

     (.find (.pmacro (n) (.lt n 2)) (.iota 4)) --> (0 1)


File: cgen.info,  Node: car/cdr,  Prev: Finding a subset of a list,  Up: List utilities

4.10.7 car/cdr
--------------

CGEN provides a small set of pmacros for those familiar with
Scheme/Lisp lists.

   * car

     Equivalent to `(.ref list 0)'.

     Example:

          (.car (1 2 3)) --> 1

   * cdr

     Return all elements of the list after the first one.

     Example:

          (.cdr (1 2 3)) --> (2 3)

   * caar

     Return the first element of the first element of the list.

     I.e., the `car' of the `car' of the list.

     Example:

          (.caar ((1 2 3) (4 5 6))) --> 1

   * cadr

     Return the second element of the list.

     I.e., the `car' of the `cdr' of the list.

     Example:

          (.cadr (1 2 3)) --> 2

   * cdar

     Return all elements after the first element of the first element
     of the list.  That's a bit of a mouthful, it's easier to
     understand by applying `car' and `cdr' in turn.

     I.e., the `cdr' of the `car' of the list.

     Example:

          (.cadr ((1 2 3) (4 5 6))) --> (2 3)

   * cddr

     I.e., the `cdr' of the `cdr' of the list.

     Return all elements of the list after the first two.

     Example:

          (.cddr (1 2 3)) --> (3)



File: cgen.info,  Node: Iteration utilities,  Next: Conditional macros,  Prev: List utilities,  Up: Preprocessor macros

4.11 Iteration utilities
========================

Macros for iterating over lists

* Menu:

* Mapping a macro over a list::   The `.map' builtin
* Iterating over a list::         The `.for-each' builtin


File: cgen.info,  Node: Mapping a macro over a list,  Next: Iterating over a list,  Up: Iteration utilities

4.11.1 Mapping a macro over a list
----------------------------------

Apply a macro to each element of a list, or set of lists, with `.map'.
The order in which each element of the list is processed is unspecified.

   The syntax is `(.map macro-name list1 [list2 ...])'.  `macro' must
take as many arguments as there are lists.

   The result is a list with `macro' applied to each element of
`listN'.  This is often useful in constructing enum and register name
lists.

   Example:

     (define-pmacro (foo name number) ((.sym X name) number))
     (.map foo (A B C D E) (.iota 5))

     -->

     ((XA 0) (XB 1) (XC 2) (XD 3) (XE 4))


File: cgen.info,  Node: Iterating over a list,  Prev: Mapping a macro over a list,  Up: Iteration utilities

4.11.2 Iterating over a list
----------------------------

Apply a macro to each element of a list, or set of lists, with
`.for-each'.  Each element of the list is guaranteed to be processed in
order.

   The syntax is `(.for-each macro list1 [list2 ...])'.  `macro' must
take as many arguments as there are lists.

   There is no result, or rather the result is always the empty list ().
Note that this macro is therefore useless for macro expansion.  It's
purpose is to process `macro' for its side-effects.  The `.exec'
builtin pmacro is useful here.


File: cgen.info,  Node: Conditional macros,  Next: Pmacro utilities,  Prev: Iteration utilities,  Up: Preprocessor macros

4.12 Conditional macros
=======================

Macros for conditional execution.

* Menu:

* Traditional `if'::         The `.if' builtin
* Traditional `case'::       The `.case' builtin
* Extended if/elseif/else::       The `.cond' builtin


File: cgen.info,  Node: Traditional `if',  Next: Traditional `case',  Up: Conditional macros

4.12.1 Traditional `if'
-----------------------

Syntax: `(.if condition then-expr [else-expr])'.

   The `condition' is evaluated, and if it is non-#f then `then-expr'
is evaluated and returned.  Otherwise, if `else-expr' is present it is
evaluated and returned.  Otherwise, the empty list `()' is returned.


File: cgen.info,  Node: Traditional `case',  Next: Extended if/elseif/else,  Prev: Traditional `if',  Up: Conditional macros

4.12.2 Traditional `case'
-------------------------

Syntax: `(.case expr ((case1-list) expr-list) [case-list] [(else
expr-list)])'

   The expression `expr' is evaluated, and then each case list is
examined in turn to look for a match.  The first case list with an
element that matches `expr' wins, its `expr-list' is evaluated and the
result of the last expression in the expression list is returned.

   If there is no successful match and no `else' part, then the empty
list `()' is returned.


File: cgen.info,  Node: Extended if/elseif/else,  Prev: Traditional `case',  Up: Conditional macros

4.12.3 Extended if/elseif/else
------------------------------

Syntax: `(.cond (expr1 expr-list) [cond-list] [(else expr-list)])'

   Each condition's expression is evaluated in turn.  The first
condition to evaluate to non-#f wins, its `expr-list' is evaluated and
the result of the last expression in the expression list is returned.

   If there is no successful condition and no `else' part, then the
empty list `()' is returned.


File: cgen.info,  Node: Pmacro utilities,  Next: Debugging utilities,  Prev: Conditional macros,  Up: Preprocessor macros

4.13 Pmacro utilities
=====================

Pmacros for working with pmacros.

* Menu:

* Re-evaluating an expression::      The `.eval' builtin
* Immediate execution of a command:: The `.exec' builtin
* Applying a pmacro to a list::      The `.apply' builtin
* Defining a pmacro inline::         The `.pmacro' builtin
* Passing pmacros as arguments::     Passing a pmacro to another pmacro
* Defining a block of locals::       The `.let', `.let*' builtins
* A block of statements::            The `.begin' builtin
* Testing if something is a pmacro:: The `.pmacro?' builtin


File: cgen.info,  Node: Re-evaluating an expression,  Next: Immediate execution of a command,  Up: Pmacro utilities

4.13.1 Re-evaluating an expression
----------------------------------

Syntax: `(.eval expr)'

   Sometimes one wishes to build up an expression in non-trivial ways
and then have the expression evaluated.  Use the `.eval' builtin pmacro
for this purpose, it re-evaluates `expr', invoking any pmacros
contained therein.

   A perhaps contrived example is when one wants to construct the
pmacro's name from a set of parameters.

   Example:

     (define-pmacro (do-foo a b) (foo a b))
     (define-pmacro (do-bar a b) (bar a b))
     (define-pmacro (doer what a b) (.eval (.list (.sym do- what) a b)))
     (doer foo 1 2) ;; --> (foo 1 2)
     (doer bar 3 4) ;; --> (bar 3 4)


File: cgen.info,  Node: Immediate execution of a command,  Next: Applying a pmacro to a list,  Prev: Re-evaluating an expression,  Up: Pmacro utilities

4.13.2 Immediate execution of a command
---------------------------------------

Syntax: `(.exec expr)'

   Sometimes one wishes to pass an expression to the `.cpu' file reader
immediately, rather than waiting for it to process the expression that
is the result of a pmacro.  This typically happens with the `.for-each'
builtin pmacro.  Use the `.exec' builtin pmacro for this purpose.  It
immediately passes `expr' to the `.cpu' file reader for processing and
returns `()' as a result.


File: cgen.info,  Node: Applying a pmacro to a list,  Next: Defining a pmacro inline,  Prev: Immediate execution of a command,  Up: Pmacro utilities

4.13.3 Applying a pmacro to a list
----------------------------------

Invoke a macro with each argument coming from an element of a list,
with `.apply'.

   The syntax is `(.apply macro-name list)'.

   The result is the result of invoking macro `macro-name'.
`macro-name' should take as many arguments as there elements in `list'.
If `macro-name' takes a variable number of trailing arguments, there
must be at least as many list elements as there are fixed arguments.

   Example:

   Example:

     (.apply .str (.iota 5)) --> "01234"

   Note that `(.str (.iota 5))' is an error.  Here the list `(0 1 2 3
4)' is passed as the first argument of `.str', which is wrong.


File: cgen.info,  Node: Defining a pmacro inline,  Next: Passing pmacros as arguments,  Prev: Applying a pmacro to a list,  Up: Pmacro utilities

4.13.4 Defining a pmacro inline
-------------------------------

Define a macro inline with `.pmacro'.  This is only supported when
passing macros as arguments to other macros, and as values for local
variables in `.let' or `.let*'.

   Example:

     (define-pmacro (load-op suffix op2-op mode ext-op)
       (begin
         (dni (.sym ld suffix) (.str "ld" suffix)
     	 ()
     	 (.str "ld" suffix " $dr,@$sr")
     	 (+ OP1_2 op2-op dr sr)
     	 (set dr (ext-op WI (mem mode sr)))
     	 ())
       )
     )

     (load-op "" OP2_12 WI (.pmacro (mode expr) expr))
     (load-op b OP2_8 QI (.pmacro (mode expr) (ext mode expr)))
     (load-op h OP2_10 HI (.pmacro (mode expr) (ext mode expr)))
     (load-op ub OP2_9 QI (.pmacro (mode expr) (zext mode expr)))
     (load-op uh OP2_11 HI (.pmacro (mode expr) (zext mode expr)))

   .pmacro's bind the same way Scheme lambda expressions do.  In the
following example, arg2 in the second pmacro is bound to the arg2
argument of the outer pmacro.

     (define-pmacro (foo arg1 arg2) ((.pmacro (bar) (+ arg2 bar)) arg1))
     (foo 3 4) ==> (+ 4 3)

   The contents of a `.pmacro' are not evaluated until the pmacro is
invoked.


File: cgen.info,  Node: Passing pmacros as arguments,  Next: Defining a block of locals,  Prev: Defining a pmacro inline,  Up: Pmacro utilities

4.13.5 Passing pmacros as arguments
-----------------------------------

Macros may be passed to other macros.

   Example:

     (define-pmacro (no-ext-expr mode expr) expr)
     (define-pmacro (ext-expr mode expr) (ext mode expr))
     (define-pmacro (zext-expr mode expr) (zext mode expr))

     (define-pmacro (load-op suffix op2-op mode ext-op)
       (begin
         (dni (.sym ld suffix) (.str "ld" suffix)
     	 ()
     	 (.str "ld" suffix " $dr,@$sr")
     	 (+ OP1_2 op2-op dr sr)
     	 (set dr (ext-op WI (mem mode sr)))
     	 ())
       )
     )

     (load-op "" OP2_12 WI no-ext-expr)
     (load-op b OP2_8 QI ext-expr)
     (load-op h OP2_10 HI ext-expr)
     (load-op ub OP2_9 QI zext-expr)
     (load-op uh OP2_11 HI zext-expr)


File: cgen.info,  Node: Defining a block of locals,  Next: A block of statements,  Prev: Passing pmacros as arguments,  Up: Pmacro utilities

4.13.6 Defining a block of locals
---------------------------------

It is often handy to assign expressions to local variables, if only to
improve readability.  This is accomplished with the `.let' and `.let*'
builtin pmacros.

   `.let' and `.let*' have the same syntax:

   `(.let local-list expr1 [expr2 ...])'

   `(.let* local-list expr1 [expr2 ...])'

   where `local-list' is a list of local variable assignments, with the
syntax `(name expr)'.  All variable names must be distinct.

   The difference is that in `.let' all expressions of all locals are
evaluated _first_ and _then_ assigned to the locals, whereas in `.let*'
each local is evaluated and assigned in turn.  This means that
expressions in `.let' cannot refer to other locals in the `.let'.  If
they do, they will get the values the variables had before the `.let'.
Also remember that symbols in pmacros are "self-quoting", so if a
symbol isn't bound to any value, its value is the symbol name.

   Example:

     (define-pmacro (load-op suffix op2-op mode ext-op)
       (.let (
              (no-ext-expr (.pmacro (mode expr) expr))
              (ext-expr (.pmacro (mode expr) (ext mode expr)))
              (zext-expr (.pmacro (mode expr) (zext mode expr)))
             )
         (begin
           (dni (.sym ld suffix) (.str "ld" suffix)
     	   ()
                (.str "ld" suffix " $dr,@$sr")
                (+ OP1_2 op2-op dr sr)
                (set dr (ext-op WI (mem mode sr)))
                ())
         )
       )
     )

     (load-op "" OP2_12 WI no-ext-expr)
     (load-op b OP2_8 QI ext-expr)
     (load-op h OP2_10 HI ext-expr)
     (load-op ub OP2_9 QI zext-expr)
     (load-op uh OP2_11 HI zext-expr)

   Note that one can also assign pmacros to local variables.

   Note that `.let*' is equivalent to a set of nested `.let'
expressions:

     (.let* ((x 1) (y x)) y)
     ;; is equivalent to
     (.let ((x 1)) (.let ((y x)) y))


File: cgen.info,  Node: A block of statements,  Next: Testing if something is a pmacro,  Prev: Defining a block of locals,  Up: Pmacro utilities

4.13.7 A block of statements
----------------------------

Sometimes one wishes to have a list of expressions (or statements) and
the context only allows one expression.  This can happen, for example,
in the `then' and `else' clauses of the `.if' builtin pmacro.  Use the
`.begin' builtin pmacro for these situations.

   Syntax: `(.begin [expr1 [expr2 ...]])'

   Each expression is evaluated in turn and the result is the result of
the last expression.


File: cgen.info,  Node: Testing if something is a pmacro,  Prev: A block of statements,  Up: Pmacro utilities

4.13.8 Testing if something is a pmacro
---------------------------------------

Sometimes one wishes to know if an argument is a pmacro or not.  This
is useful when one is writing a pmacro that has a parameter that is
either a pmacro or is not (e.g., it could be an rtl function instead).
When the parameter is a pmacro one might like to `.apply' it to another
argument, and if not one might like to simply construct a list of it
and the other argument.

   Syntax: `(.pmacro? arg)'

   Example:

     (define-pmacro (compare a b) (if (eq a b) 1 0))
     (define-pmacro (maybe-apply fun args)
       (.if (.pmacro? fun)
            (.apply fun args)
            (.splice fun (.unsplice args))))
     (define-pmacro (gen-semantics semfun args)
       (set dest (maybe-apply semfun args)))
     (gen-semantics add (op1 op2))) ;; ==> (set dest (add op1 op2))
     (gen-semantics compare (op1 op2))) ;; ==> (set dest (if (eq op1 op2) 1 0))


File: cgen.info,  Node: Debugging utilities,  Next: Comparisons,  Prev: Pmacro utilities,  Up: Preprocessor macros

4.14 Debugging utilities
========================

* Menu:

* .print::     Printing a diagnostic message
* .dump::      Printing arbitrarily complex objects
* .error::     Signalling an error has occurred


File: cgen.info,  Node: .print,  Next: .dump,  Up: Debugging utilities

4.14.1 .print
-------------

Syntax: `(.print expr1 [...])'

   Evaluate and print the supplied expressions.  This is useful for
debugging and logging messages.

   NOTE: Strings are printed without enclosing quotes.  Use `dump' if
you want to print strings with enclosing quotes.

   The result is the empty list `()'.


File: cgen.info,  Node: .dump,  Next: .error,  Prev: .print,  Up: Debugging utilities

4.14.2 .dump
------------

Syntax: `(.dump expr1 [...])'

   Evaluate and print the supplied expressions.  This is useful for
debugging and logging messages.

   NOTE: Strings are printed with enclosing quotes.  Use `print' if you
want to print strings without enclosing quotes.

   The result is the empty list `()'.


File: cgen.info,  Node: .error,  Prev: .dump,  Up: Debugging utilities

4.14.3 .error
-------------

Syntax: `(.error expr1 [...])'

   Evaluate the supplied expressions and signal an error.  The
expressions are typically error messages, often with the object that
caused the error.


File: cgen.info,  Node: Comparisons,  Next: Arithmetic functions,  Prev: Debugging utilities,  Up: Preprocessor macros

4.15 Comparisons
================

Builtin macros for comparing objects.

   In CGEN "true" is represented by `#t' and "false" is represented by
`#f'.

* Menu:

* .equal?::      Deep comparison
* .andif::       && in C
* .orif::        || in C
* .not::         ! in C
* .eq::          Shallow comparison
* .ne::          Shallow comparison
* .lt::          Less than
* .gt::          Greater than
* .le::          Less than or equal to
* .ge::          Greater than or equal to


File: cgen.info,  Node: .equal?,  Next: .andif,  Up: Comparisons

4.15.1 .equal?
--------------

Syntax: `(.equal? x y)'

   Return #t if `x' is equal to `y', otherwise #f.

   A "deep" comparison is used.  I.e., if `x' and `y' are lists, list
elements are recursively compared

   Examples:

     (.equal? "abc" "abc") --> #t
     (.equal? symbol1 symbol1) --> #t
     (.equal? ((1 2 3) (4 5 6)) ((1 2 3) (4 5 6))) --> #t


File: cgen.info,  Node: .andif,  Next: .orif,  Prev: .equal?,  Up: Comparisons

4.15.2 .andif
-------------

Syntax: `(.andif [expr1 [expr2 ...]])'

   Each expression is evaluated in turn.  If an expression evaluates to
false (`#f') then evaluation stops and the result is `#f'.  If all
expressions evaluate to non-`#f', then the value of the last expression
is returned.

   Note that this is a special form.  Just like `&&' in C, evaluation
of subsequent expressions is not done once an expression is found that
evaluates to "false".

   Examples:

     (.andif 1 #f 2) --> #f
     (.andif 1 2 3) --> 3
     (.andif) --> #t


File: cgen.info,  Node: .orif,  Next: .not,  Prev: .andif,  Up: Comparisons

4.15.3 .orif
------------

Syntax: `(.orif [expr1 [expr2 ...]])'

   Each expression is evaluated in turn.  If an expression evaluates to
non-false (`#f') then evaluation stops and the result is the value of
the first non-`#f' expression.  If all expressions evaluate to `#f',
then the result is `#f'.

   Note that this is a special form.  Just like `||' in C, evaluation
of subsequent expressions is not done once an expression is found that
evaluates to non-"false".

   Examples:

     (.orif 1 2 3) --> 1
     (.orif #f #f #f) --> #f
     (.orif) --> #f


File: cgen.info,  Node: .not,  Next: .eq,  Prev: .orif,  Up: Comparisons

4.15.4 .not
-----------

Syntax: `(.not expr)'

   If `expr' is `#f' return `#t'.  If `expr' is non-`#f' return `#f'.

   _Note that (.not 0) is not 1, it is #f!_.


File: cgen.info,  Node: .eq,  Next: .ne,  Prev: .not,  Up: Comparisons

4.15.5 .eq
----------

Syntax: `(.eq x y)'

   Return "true" if `x' equals `y', otherwise "false".

   Note that this does _not_ do a deep comparison, and can only be used
with symbols, strings, and numbers.  Both `x' and `y' must be the same
type.

   Examples:

     (.eq 1 1) -> #t
     (.eq 0 1) -> #f
     (.eq 0 one) -> error
     (.eq one one) -> #t
     (.eq zero one) -> #f
     (.eq "abc" "abc") -> #t
     (.eq "abc" "def") -> #f


File: cgen.info,  Node: .ne,  Next: .lt,  Prev: .eq,  Up: Comparisons

4.15.6 .ne
----------

Syntax: `(.ne x y)'

   Return "true" if `x' does not equal `y', otherwise "false".

   Note that this does _not_ do a deep comparison, and can only be used
with symbols, strings, and numbers.  Both `x' and `y' must be the same
type.

   Examples:

     (.ne 1 1) -> #f
     (.ne 0 1) -> #t
     (.ne 0 one) -> error
     (.ne one one) -> #f
     (.ne zero one) -> #t
     (.ne "abc" "abc") -> #f
     (.ne "abc" "def") -> #t


File: cgen.info,  Node: .lt,  Next: .gt,  Prev: .ne,  Up: Comparisons

4.15.7 .lt
----------

Syntax: `(.lt x y)'

   Return "true" if `x' is less than `y', otherwise "false".

   Both `x' and `y' must be numbers.


File: cgen.info,  Node: .gt,  Next: .le,  Prev: .lt,  Up: Comparisons

4.15.8 .gt
----------

Syntax: `(.gt x y)'

   Return "true" if `x' is greater than `y', otherwise "false".

   Both `x' and `y' must be numbers.


File: cgen.info,  Node: .le,  Next: .ge,  Prev: .gt,  Up: Comparisons

4.15.9 .le
----------

Syntax: `(.le x y)'

   Return "true" if `x' is less than or equal to `y', otherwise "false".

   Both `x' and `y' must be numbers.


File: cgen.info,  Node: .ge,  Prev: .le,  Up: Comparisons

4.15.10 .ge
-----------

Syntax: `(.ge x y)'

   Return "true" if `x' is greater than or equal to `y', otherwise
"false".

   Both `x' and `y' must be numbers.


File: cgen.info,  Node: Arithmetic functions,  Next: Logical functions,  Prev: Comparisons,  Up: Preprocessor macros

4.16 Arithmetic functions
=========================

* Menu:

* .add::      Addition
* .sub::      Subtraction
* .mul::      Multiplication
* .div::      Integer division
* .rem::      Integer remainder


File: cgen.info,  Node: .add,  Next: .sub,  Up: Arithmetic functions

4.16.1 .add
-----------

Syntax: `(.add x y)'

   Return `x' + `y'.


File: cgen.info,  Node: .sub,  Next: .mul,  Prev: .add,  Up: Arithmetic functions

4.16.2 .sub
-----------

Syntax: `(.sub x y)'

   Return `x' - `y'.


File: cgen.info,  Node: .mul,  Next: .div,  Prev: .sub,  Up: Arithmetic functions

4.16.3 .mul
-----------

Syntax: `(.mul x y)'

   Return `x' * `y'.


File: cgen.info,  Node: .div,  Next: .rem,  Prev: .mul,  Up: Arithmetic functions

4.16.4 .div
-----------

Syntax: `(.div x y)'

   Return the quotient of `x' divided by `y'.

   Only integer division is supported, both `x' and `y' must be
integers.


File: cgen.info,  Node: .rem,  Prev: .div,  Up: Arithmetic functions

4.16.5 .rem
-----------

Syntax: `(.rem x y)'

   Return the remainder of `x' divided by `y'.

   Only integer division is supported, both `x' and `y' must be
integers.


File: cgen.info,  Node: Logical functions,  Next: Internal use pmacros,  Prev: Arithmetic functions,  Up: Preprocessor macros

4.17 Logical functions
======================

Builtin macros for shifts and bitwise functions.

* Menu:

* .sll::       Shift left logical
* .srl::       Shift right logical
* .sra::       Shift right arithmetic
* .and::       Bitwise and
* .or::        Bitwise or
* .xor::       Bitwise exclusive-or
* .inv::       Bitwise inversion


File: cgen.info,  Node: .sll,  Next: .srl,  Up: Logical functions

4.17.1 .sll
-----------

Syntax: `(.sll x n)'

   Shift `x' left by `n' bits.  Zeroes are shifted into the low-order
bits.

   `n' must be a non-negative integer.


File: cgen.info,  Node: .srl,  Next: .sra,  Prev: .sll,  Up: Logical functions

4.17.2 .srl
-----------

Syntax: `(.srl x n)'

   Shift `x' right by `n' bits.

   `x' _must_ be a non-negative integer.  Numbers at the pmacro level
have "infinite precision", and shifting zeroes into the high-order bits
of infinite-precision negative numbers is undefined.

   `n' must be a non-negative integer.


File: cgen.info,  Node: .sra,  Next: .and,  Prev: .srl,  Up: Logical functions

4.17.3 .sra
-----------

Syntax: `(.sra x n)'

   Shift `x' right arithmetically by `n' bits.  The sign bit of `x' is
shifted into the high-order bits.

   `n' must be a non-negative integer.


File: cgen.info,  Node: .and,  Next: .or,  Prev: .sra,  Up: Logical functions

4.17.4 .and
-----------

Syntax: `(.and x y)'

   Return the bitwise `and' of `x' and `y'.


File: cgen.info,  Node: .or,  Next: .xor,  Prev: .and,  Up: Logical functions

4.17.5 .or
----------

Syntax: `(.or x y)'

   Return the bitwise `or' of `x' and `y'.


File: cgen.info,  Node: .xor,  Next: .inv,  Prev: .or,  Up: Logical functions

4.17.6 .xor
-----------

Syntax: `(.xor x y)'

   Return the bitwise `exclusive-or' of `x' and `y'.


File: cgen.info,  Node: .inv,  Prev: .xor,  Up: Logical functions

4.17.7 .inv
-----------

Syntax: `(.inv x)'

   Return the bitwise `inversion' of `x'.


File: cgen.info,  Node: Internal use pmacros,  Prev: Logical functions,  Up: Preprocessor macros

4.18 Internal use pmacros
=========================

This section documents pmacros that are for internal use only.  Today
there's only one, `.internal-test', and it is used by the testsuite.

4.18.1 .internal-test
---------------------

Syntax: `(.internal-test expr)'

   Execute `expr' as a Scheme expression and return #f if the
expression returns #f and return #t if the expression returns non-#f.

   This is for use in the CGEN testsuite only.  See the testsuite for
usage examples.


File: cgen.info,  Node: Porting,  Next: Opcodes,  Prev: Preprocessor macros,  Up: Top

5 Porting
*********

This chapter describes how to do a CGEN port.  It focuses on doing
binutils and simulator ports, but the procedure should be generally
applicable.

* Menu:

* Introduction to porting::
* Supported Guile versions::
* Running configure::
* Writing a CPU description file::
* Interactive development::
* Doing an opcodes port::
* Doing a GAS port::
* Building a GAS test suite::
* Doing a simulator port::
* Building a simulator test suite::


File: cgen.info,  Node: Introduction to porting,  Next: Supported Guile versions,  Up: Porting

5.1 Introduction to porting
===========================

Doing a GNU tools port for a new processor basically consists of
porting the following components more or less in order.  The order can
be changed, of course, but the following order is reasonable.
Certainly things like BFD and opcodes need to be finished earlier than
others.  Bugs in earlier pieces are often not found until testing later
pieces so each piece isn't necessarily finished until they all are.

   * DejaGNU

   * BFD

   * CGEN

   * Opcodes

   * GAS

   * Binutils

   * Linker (`ld')

   * newlib

   * libgloss

   * simulator

   * GCC

   * GDB

   The use of CGEN affects the opcodes, GAS, and simulator portions
only.  As always, the M32R port is a good reference base.

   One goal of CGEN is to describe the CPU in an application
independent manner so that program generators can do all the repetitive
work of generating code and tables for each CPU that is ported.

   For opcodes, several files are generated.  No additional code need be
written in the opcodes directory although as an escape hatch the user
can add target specific code to file <arch>.opc in the CGEN cpu source
directory.  These functions will be included in the relevant generated
files.  An example of when you need to create an <arch>.opc file is when
there are special pseudo-ops that need to be parsed, for example the
high/shigh pseudo-ops of the M32R.  *Note Doing an opcodes port::.

   For GAS, no files are generated (except test cases!) so the port is
done more or less like the other GAS ports except that the assembler
uses the CGEN-built opcode table plus `toplevel/gas/cgen.[ch]'.

   For the simulator, several files are built, and other support files
need to be written.  *Note Doing a simulator port::.


File: cgen.info,  Node: Supported Guile versions,  Next: Running configure,  Prev: Introduction to porting,  Up: Porting

5.2 Supported Guile versions
============================

In order to avoid suffering from the bug of the day when using
snapshots, CGEN development has been confined to Guile releases only.
CGEN has been tested with and supports Guile versions `1.6.8' and
`1.8.5'.  As time passes older versions of Guile will no longer be
supported.


File: cgen.info,  Node: Running configure,  Next: Writing a CPU description file,  Prev: Supported Guile versions,  Up: Porting

5.3 Running `configure'
=======================

When doing porting or maintenance activity with CGEN, it's a good idea
to configure the build tree with the `--enable-cgen-maint' option.
This adds the necessary dependencies to the `toplevel/opcodes' and
`toplevel/sim' directories so that when the `.cpu' file is changed the
makefiles will regenerated the corresponding sources.

   CGEN uses Guile so it must be installed.


File: cgen.info,  Node: Writing a CPU description file,  Next: Interactive development,  Prev: Running configure,  Up: Porting

5.4 Writing a CPU description file
==================================

The first step in doing a CGEN port is writing a CPU description file.
The best way to do that is to take an existing file (such as the M32R)
and use it as a template.

   Writing a CPU description file generally involves writing each of the
following types of entries, in order.  *Note RTL::, for detailed
descriptions of each type of entry that appears in the description file.

* Menu:

* Conventions::                      Programming style conventions
* simplify.inc::                     Simplifying writing `.cpu' files
* Names and comments::               Special note on names and comments
* Writing define-arch::              Architecture wide specs
* Writing define-isa::               Instruction set characteristics
* Writing define-cpu::               CPU families
* Writing define-mach::              Machine variants
* Writing define-model::             Models of each machine variant
* Writing define-hardware::          Hardware elements
* Writing define-ifield::            Instruction fields
* Writing define-normal-insn-enum::  Instruction enums
* Writing define-operand::           Instruction operands
* Writing define-insn::              Instructions
* Writing define-macro-insn::        Macro instructions
* Using define-pmacro::              Preprocessor macros
* Splicing list arguments::          List arguments in macros


File: cgen.info,  Node: Conventions,  Next: simplify.inc,  Up: Writing a CPU description file

5.4.1 Conventions
-----------------

First a digression on conventions and programming style.

   * `define-foo' vs. `define-normal-foo'

     Each CPU description `define-' entry generally provides two forms:
     the normal form and the general form.  The normal form has a
     simple, fixed-argument syntax that allows one to specify the most
     popular elements.  When one needs to specify more obscure elements
     of the entry one uses the long form which is a list of name/value
     pairs.  The naming convention is to call the normal form
     `define-normal-foo' and the general form `define-foo'.

   * Parentheses placement

     Consider:

          (define-normal-insn-enum
            insn-op1 "insn format enums" () f-op1 OP1_
            (ADD ADDC SUB SUBC
             AND OR   XOR INV)
          )

     All Lisp/Scheme code I've read puts the trailing parenthesis on the
     previous line.  CGEN programming style says the last trailing
     parenthesis goes on a line by itself.  If someone wants to put
     forth an argument of why this should change, please do.  I like
     putting the very last parenthesis on a line by itself in column 1
     because it makes it easier to traverse the file with a parenthesis
     matching keystroke.

   * `StudlyCaps' vs. `_' vs. `-'

     The convention is to have most things lowercase with words
     separated by `-'.  Things that are uppercase are fixed and well
     defined: enum values and mode names.  This convention must be
     followed.

   * Integers

     There are two things to keep in mind regarding integers in CGEN.

       1. Unspecified width

          Integers in CGEN generally don't specify a width.  The width
          is imposed by context.

       2. RTL canonicalization

          Integers in RTL may simply be written as a number, or in the
          full canonical form as `(const [<option-list>] [<mode>]
          <value>)'.

          The "option list", if specified, must be `()' as there are
          currently no options for constants.  It is optional and is
          generally elided when written.

          The "mode" of the number specifies the precision.  The
          default mode is `INT' meaning arbitrary precision.

          In RTL, whether to write just the number, e.g. `24', or the
          full canonical form, e.g., `(const () INT 24)', or anything
          in between is a matter of style.




File: cgen.info,  Node: simplify.inc,  Next: Names and comments,  Prev: Conventions,  Up: Writing a CPU description file

5.4.2 simplify.inc
------------------

The file `simplify.inc' provides several pmacros that help simplify
writing `.cpu' files.

   To use it add the following to your `.cpu' file.

     (include "simplify.inc")

   `simplify.inc' provides the following pmacros:

   * define-normal-enum (*note define-normal-enum:
     a-define-normal-enum.)

   * define-normal-insn-enum (*note define-normal-insn-enum:
     a-define-normal-insn-enum.)

   * define-normal-ifield (*note define-normal-ifield:
     a-define-normal-ifield.)

   * df (*note df: a-df.)

   * dnf (*note dnf: a-dnf.)

   * define-normal-multi-ifield (*note define-normal-multi-ifield:
     a-define-normal-multi-ifield.)

   * dnmf (*note dnmf: a-dnmf.)

   * dsmf (*note dsmf: a-dsmf.)

   * define-normal-hardware (*note define-normal-hardware:
     a-define-normal-hardware.)

   * dnh (*note dnh: a-dnh.)

   * define-simple-hardware (*note define-simple-hardware:
     a-define-simple-hardware.)

   * dsh (*note dsh: a-dsh.)

   * define-normal-operand (*note define-normal-operand:
     a-define-normal-operand.)

   * dno (*note dno: a-dno.)

   * dnop (*note dnop: a-dnop.)

   * dndo

   * define-normal-insn (*note define-normal-insn:
     a-define-normal-insn.)

   * dni (*note dni: a-dni.)

   * define-normal-macro-insn (*note define-normal-macro-insn:
     a-define-normal-macro-insn.)

   * dnmi (*note dnmi: a-dnmi.)



File: cgen.info,  Node: Names and comments,  Next: Writing define-arch,  Prev: simplify.inc,  Up: Writing a CPU description file

5.4.3 Names and comments
------------------------

Most description entries have a few fields in common: name, comment,
and attrs (for attributes).

   The `name' and `comment' fields have a special property to help
simplify writing description files.

   The proper type for a name is a `symbol' and the proper type for a
comment is `string'.  It is sometimes useful, however, to construct
names and comments from a list of values.  To support this without
forcing the description file writer to have to explicitly construct a
name or comment from pieces, CGEN accepts a list as a valid `name' or
`comment' field, and will (recursively) append each element
automagically.  Each list must consist of symbols, strings, and numbers,
or lists.  CGEN will automagically convert the value to a symbol for a
name field, and a string for a comment field.

   Example:

     (define-insn (name (add 3))
                  (comment (("This is a" " comment")
                            " constructed as a list."))
                  ...)

   The name of this instruction is "add3" and the comment is "This is a
comment constructed as a list.".


File: cgen.info,  Node: Writing define-arch,  Next: Writing define-isa,  Prev: Names and comments,  Up: Writing a CPU description file

5.4.4 Writing define-arch
-------------------------

Various simple and architecture-wide common things like the name of the
processor must be defined somewhere, so all of this stuff is put under
`define-arch'.

   This must be the first entry in the description file.

   *Note Architecture variants::, for details.

   Here's an example from `m32r.cpu':

     (define-arch
       (name m32r) ; name of cpu family
       (comment "Renesas M32R")
       (default-alignment aligned)
       (insn-lsb0? #f)
       (machs m32r m32rx m32r2)
       (isas m32r)
     )


File: cgen.info,  Node: Writing define-isa,  Next: Writing define-cpu,  Prev: Writing define-arch,  Up: Writing a CPU description file

5.4.5 Writing define-isa
------------------------

There are two purposes to `define-isa'.  The first is to specify
parameters needed to decode instructions.

   The second is to give the instruction set a name.  This is important
for architectures like the ARM where one CPU can execute multiple
instruction sets.

   *Note Architecture variants::, for details.

   Here's an example from `arm.cpu':

     (define-isa
       (name thumb)
       (comment "ARM Thumb instruction set (16 bit insns)")
       (base-insn-bitsize 16)
       (decode-assist (15 14 13 12 11 10 9 8))
       (setup-semantics (set-quiet (reg h-gr 15) (add pc 4)))
     )


File: cgen.info,  Node: Writing define-cpu,  Next: Writing define-mach,  Prev: Writing define-isa,  Up: Writing a CPU description file

5.4.6 Writing define-cpu
------------------------

CPU families are an internal and artificial classification designed to
collect processor variants that are sufficiently similar together under
one roof for the simulator.  What is "sufficiently similar" is up to
the programmer.  For example, if the only difference between two
processor variants is that one has a few extra instructions, there's no
point in treating them separately in the simulator.

   When simulating the variant without the extra instructions, said
instructions are marked as "invalid".  On the other hand, putting 32
and 64 bit variants of an architecture under one roof is problematic
since the word size is different.  What "under one roof" means is left
fuzzy for now, but basically the simulator engine has a collection of
structures defining internal state, and "CPU families" minimize the
number of copies of generated code that manipulate this state.

   *Note Architecture variants::, for details.

   Here's an example from `openrisc.cpu':

     (define-cpu
       ; CPU names must be distinct from the architecture name and machine names.
       ; The "b" suffix stands for "base" and is the convention.
       ; The "f" suffix stands for "family" and is the convention.
       (name openriscbf)
       (comment "OpenRISC base family")
       (endian big)
       (word-bitsize 32)
     )


File: cgen.info,  Node: Writing define-mach,  Next: Writing define-model,  Prev: Writing define-cpu,  Up: Writing a CPU description file

5.4.7 Writing define-mach
-------------------------

CGEN uses "mach" in the same sense that BFD uses "mach".  "Mach", which
is short for `machine', defines a variant of the architecture.

   *Note Architecture variants::, for details.

   Here's an example from `m32r.cpu':

     (define-mach
       (name m32rx)
       (comment "M32RX cpu")
       (cpu m32rxf)
     )


File: cgen.info,  Node: Writing define-model,  Next: Writing define-hardware,  Prev: Writing define-mach,  Up: Writing a CPU description file

5.4.8 Writing define-model
--------------------------

When describing a CPU, in any context, there is "architecture" and
there is "implementation".  In CGEN parlance, a "model" is an
implementation of a "mach".  Models specify pipeline and other
performance related characteristics of the implementation.

   Some architectures bring pipeline details up into the architecture
(rather than making them an implementation detail).  It's not clear yet
how to handle all the various possibilities so at present this is done
on a case-by-case basis.  Maybe a straightforward solution will emerge.

   *Note Model variants::, for details.

   Here's an example from `arm.cpu':

     (define-model
       (name arm710)
       (comment "ARM 710 microprocessor")
       (mach arm7tdmi)
       (unit u-exec "Execution Unit" ()
     	1 1 ; issue done
     	() () () ())
     )


File: cgen.info,  Node: Writing define-hardware,  Next: Writing define-ifield,  Prev: Writing define-model,  Up: Writing a CPU description file

5.4.9 Writing define-hardware
-----------------------------

The registers of the processor are specified with `define-hardware'.
Also, immediate constants and addresses are defined to be "hardware".
By convention, all hardware elements names are prefaced with `h-'.
This convention must be followed.

   Pre-defined hardware elements are:

`h-memory'
     Normal CPU memory(1)

`h-sint'
     signed integer

`h-uint'
     unsigned integer

`h-addr'
     an address

`h-iaddr'
     an instruction address

   Where are floats you ask?  They'll be defined when the need arises.

   The program counter is named `h-pc' and must be specified.  It is
not a builtin element as sometimes architectures need to modify its
behaviour (in the get/set specs).

   *Note Hardware elements::, for details.

   Here's an example from `arm.cpu':

     (define-hardware
       (name h-gr)
       (comment "general registers")
       (attrs PROFILE CACHE-ADDR)
       (type register WI (16))
       (indices extern-keyword gr-names)
     )

   ---------- Footnotes ----------

   (1) A temporary simplifying assumption is to treat all memory
identically.  Being able to specify various kinds of memory (e.g.
on-chip RAM,ROM) is work-in-progress.


File: cgen.info,  Node: Writing define-ifield,  Next: Writing define-normal-insn-enum,  Prev: Writing define-hardware,  Up: Writing a CPU description file

5.4.10 Writing define-ifield
----------------------------

Writing instruction field entries involves analyzing the instruction set
and creating an entry for each field.  If a field has multiple purposes,
one can create separate entries for each intended purpose.  The names
should generally follow the names used by the architecture reference
manual.

   By convention, all instruction field names are prefaced with `f-'.
This convention must be followed.

   CGEN tries to allow the use of the bit numbering as found in the
architecture reference manual.  This minimizes transcription errors
both when writing the `.cpu' file and later when communicating field
info to people.

   There are two key pieces of data that CGEN uses to organize field
specification: the default insn word size (in bits), and whether bit
number 0 is the LSB (least significant bit) or the MSB (most
significant bit).

   In the general case, fields are described with 4 numbers:
word-offset, word-length, start, and length.  All instruction fields
live in exactly one word and must be contiguous.(1) Non-contiguous
fields are specified with "multi-ifields" which are fields built up out
of several smaller typically disjoint fields.  The size of the word
depends on the context.  `word-offset' specifies the offset in bits
from the start of the insn to the word containing the field, it must be
a multiple of 8.  `word-length' specifies the size in bits of the word
containing the field, it also must be a multiple of 8.  `start'
specifies the position of the MSB of the field in the word.  `length'
specifies the size in bits of the field.

   *Note Instruction fields::, for details.

   Example.

   Suppose an ISA has instructions that are normally 16 bits, but has
instructions that may take an additional 32 bit immediate and
optionally an additional 16 bit immediate after that.  Also suppose the
ISA numbers the bits starting from the LSB.

   default-insn-word-bitsize = 16, lsb0? = #t

   An instruction with four 4 bit fields, one 32 bit immediate and one
16 bit immediate might be:


       +-----+-----+----+----+--------+--------+
       | op1 | op2 | r1 | r2 | simm32 | simm16 |
       +-----+-----+----+----+--------+--------+

                 word-offset  word-length  start  length
     f-op1:           0            16        15      4
     f-op2:           0            16        11      4
     f-r1:            0            16         7      4
     f-r2:            0            16         3      4
     f-simm32:       16            32        31     32
     f-simm16:       48            16        15     16

   If lsb0? = #f, then the example becomes:


                 word-offset  word-length  start  length
     f-op1:           0            16         0      4
     f-op2:           0            16         4      4
     f-r1:            0            16         8      4
     f-r2:            0            16        12      4
     f-simm32:       16            32         0     32
     f-simm16:       48            16         0     16

   Endianness for the purposes of this example is irrelevant.  In the
word containing op1,op2,r1,r2, op1 is in the most significant nibble
and r2 is in the least significant nibble.

   For a large number of cases specifying all four numbers is excessive.
With careful redefinition of the starting bit number, one can get away
with only specifying start,length.  Imagine several words of the
default insn word size laid out from the start of the insn.  On top of
that lay the field.  Now pick the minimal set of words that are
required to contain the field.  That is the "word" we use.  The `start'
value is basically computed by adding the offset of the first
containing word to the starting bit of the field in the word.  It's
slightly more complicated than that because lsb0? and the word's size
must be taken into account.  This is best illustrated by rewriting the
above example:


     lsb0? = #t

                 start  length
     f-op1:        15      4
     f-op2:        11      4
     f-r1:          7      4
     f-r2:          3      4
     f-simm32:     47     32
     f-simm16:     63     16

     lsb0? = #f

                 start  length
     f-op1:         0      4
     f-op2:         4      4
     f-r1:          8      4
     f-r2:         12      4
     f-simm32:     16     32
     f-simm16:     48     16

   Note: This simpler definition doesn't work in all cases.  Where it
doesn't the full-blown definition must be used.

   There are currently no shorthand macros for specifying the full-blown
definition.  It is recommended that if you have to use one that you
write a macro to reduce typing.

   Written out the full blown way, the f-op1 field would be specified
as:


     (define-ifield
       (name f-op1)
       (comment "f-op1")
       (attrs) ; no attributes, could be elided if one wants
       (word-offset 0)
       (word-length 16)
       (start 15)
       (length 4)
       (mode UINT)
       (encode #f) ; no special encoding, could be elided if one wants
       (decode #f) ; no special encoding, could be elided if one wants
     )

   A macro to simplify that could be written as:


     ; dwf: define-word-field (??? pick a better name)

     (define-pmacro (dwf x-name x-comment x-attrs
                         x-word-offset x-word-length x-start x-length
                         x-mode x-encode x-decode)
       "Define a field including its containing word."
       (define-ifield
         (name x-name)
         (comment x-comment)
         (.splice attrs (.unsplice x-attrs))
         (word-offset x-word-offset)
         (word-length x-word-length)
         (start x-start)
         (length x-length)
         (mode x-mode)
         (.splice encode (.unsplice x-encode))
         (.splice decode (.unsplice x-decode))
         )
     )

   The `.splice' is necessary because `attrs', `encode', and `decode'
take a list as an argument.

   One would then write f-op1 as:


     (dwf f-op1 "f-op1" () 0 16 15 4 UINT #f #f)

   ---------- Footnotes ----------

   (1) This doesn't include fields like multi-ifields.


File: cgen.info,  Node: Writing define-normal-insn-enum,  Next: Writing define-operand,  Prev: Writing define-ifield,  Up: Writing a CPU description file

5.4.11 Writing define-normal-insn-enum
--------------------------------------

Writing instruction enum entries involves analyzing the instruction set
and attaching names to the opcode fields.  For example, if a field named
`op1' is used to select which of add, addc, sub, subc, and, or, xor,
and inv instructions, one could write something like the following:

     (define-normal-insn-enum
       insn-op1 "insn format enums" () f-op1 OP1_
       (ADD ADDC SUB SUBC
        AND OR   XOR INV)
     )

   These entries simplify instruction definitions by giving a name to a
particular value for a particular instruction field.  By convention,
enum names are uppercase.  This convention must be followed.

   *Note Enumerated constants::, for details.


File: cgen.info,  Node: Writing define-operand,  Next: Writing define-insn,  Prev: Writing define-normal-insn-enum,  Up: Writing a CPU description file

5.4.12 Writing define-operand
-----------------------------

Operands are what instruction semantics use to refer to hardware
elements.  The typical use of an operand is to map instruction fields to
hardware.  For example, if field `f-r2' is used to specify one of the
registers defined by the `h-gr' hardware entry, one could write
something like the following:

   `(dnop sr "source register" () h-gr f-r2)'

   `dnop' is short for "define normal operand" (1).

   *Note Instruction operands::, for more information.

   ---------- Footnotes ----------

   (1) A profound aversion to typing causes me to often provide brief
names of things that get typed a lot.


File: cgen.info,  Node: Writing define-insn,  Next: Writing define-macro-insn,  Prev: Writing define-operand,  Up: Writing a CPU description file

5.4.13 Writing define-insn
--------------------------

A large part of writing a `.cpu' file is going through the CPU manual
and writing an entry for each instruction.  Instructions specific to a
particular machine variant are indicated so with the `MACH' attribute.
Example:

     (define-normal-insn
       add "add instruction"
       ((MACH mach1)) ; or (MACH mach1,mach2,...) for multiple variants
       ...
     )

   The `base' machine is a predefined machine variant that includes
instructions available to all variants, and is the default if no `MACH'
attribute is specified.

   *Note Instructions::, for details.

   When the `.cpu' file is processed, CGEN will analyze the semantics
to determine:

   * input operands

     The list of hardware elements read by the instruction.

   * output operands

     The list of hardware elements written by the instruction.

   * attributes

     Instruction attributes that can be computed from the semantics.

     CTI: control transfer instruction, generally a branch.

        * UNCOND-CTI

          The instruction unconditionally sets pc.

        * COND-CTI

          The instruction conditionally sets pc.

        * SKIP-CTI

          NB. This is an experimental attribute.  Its usage needs to
          evolve.

        * DELAY-SLOT

          NB. This is an experimental attribute.  Its usage needs to
          evolve.


   CGEN will also try to simplify the semantics as much as possible:

   * Constant folding

     Expressions involving constants are simplified and any resulting
     non-taken paths of conditional expressions are discarded.


File: cgen.info,  Node: Writing define-macro-insn,  Next: Using define-pmacro,  Prev: Writing define-insn,  Up: Writing a CPU description file

5.4.14 Writing define-macro-insn
--------------------------------

Some instructions are really aliases for other instructions, maybe even
a sequence of them.  For example, an architecture that has a general
decrement-then-store instruction might have a specialized version of
this instruction called `push' supported by the assembler.  These are
handled with "macro instructions".

   *Note Macro-instructions::, for details.

   Macro instructions are used by the assembler/disassembler only.
They are not used by the simulator.

   For example, if this was the real instruction:

     (dni st-minus "st-" ()
          "st $src1,$src2"
          (+ OP1_2 OP2_7 src1 src2)
          (sequence ((WI new-src2))
     	       (set new-src2 (sub src2 (const 4)))
     	       (set (mem WI new-src2) src1)
     	       (set src2 new-src2))
          ()
     )

   One could write a `push' variant with:

     (dnmi push "push" ()
       "push $src1"
       (emit st-minus src1 (src2 15)) ; "st %0,sp"
     )


File: cgen.info,  Node: Using define-pmacro,  Next: Splicing list arguments,  Prev: Writing define-macro-insn,  Up: Writing a CPU description file

5.4.15 Using define-pmacro
--------------------------

When a group of entries, say instructions, share similar information, a
macro (in the C preprocessor sense) can be used to simplify the
description.  This can be used to save a lot of typing, which can also
improve readability since often one page of code is easier to understand
than four.

   *Note Preprocessor macros::, for details.

   Here is an example from the M32R port.

     (define-pmacro (bin-op mnemonic op2-op sem-op imm-prefix imm)
       (begin
          (dni mnemonic
     	  (.str mnemonic " reg/reg")
     	  ()
     	  (.str mnemonic " $dr,$sr")
     	  (+ OP1_0 op2-op dr sr)
     	  (set dr (sem-op dr sr))
     	  ()
          )
          (dni (.sym mnemonic "3")
     	  (.str mnemonic " reg/" imm)
     	  ()
     	  (.str mnemonic "3 $dr,$sr," imm-prefix "$" imm)
     	  (+ OP1_8 op2-op dr sr imm)
     	  (set dr (sem-op sr imm))
     	  ()
          )
        )
     )
     (bin-op add OP2_10 add "$hash" slo16)
     (bin-op and OP2_12 and ""      uimm16)
     (bin-op or  OP2_14 or  "$hash" ulo16)
     (bin-op xor OP2_13 xor ""      uimm16)

   `.sym/.str' are short for Scheme's `symbol-append' and
`string-append' operations and are conceptually the same as the C
preprocessor's `##' concatenation operator.  *Note Symbol
concatenation::, and *Note String concatenation::, for details.


File: cgen.info,  Node: Splicing list arguments,  Prev: Using define-pmacro,  Up: Writing a CPU description file

5.4.16 Splicing arguments
-------------------------

Several cpu description elements take multiple arguments, as opposed to
a single argument (even if that single argument is a list).  When
constructing a call to define-* in a pmacro, these elements must have
their arguments spliced in to achieve the proper syntax.

   This is best explained with an example.  Here's a simplifying macro
for writing ifield definitions with every element specified.

   *Note List splicing::, for details.


     ; dwf: define-word-field

     (define-pmacro (dwf x-name x-comment x-attrs
                         x-word-offset x-word-length x-start x-length
                         x-mode x-encode x-decode)
       "Define a field including its containing word."
       (define-ifield
         (name x-name)
         (comment x-comment)
         (.splice attrs (.unsplice x-attrs))
         (word-offset x-word-offset)
         (word-length x-word-length)
         (start x-start)
         (length x-length)
         (mode x-mode)
         (.splice encode (.unsplice x-encode))
         (.splice decode (.unsplice x-decode))
         )
     )

   The `.splice' is necessary because `attrs', `encode', and `decode'
take (potentially) multiple arguments.

   One would then write f-disp16 as:

     (dwf f-disp16 "f-disp16" (PCREL-ADDR RELOC) 16 16 15 16 INT
         ((value pc) (sra WI (sub WI value pc) (const 2)))
         ((value pc) (add WI (sll WI value (const 2)) pc)))

   It will get expanded as:

     (define-ifield
       (name f-disp16)
       (comment "f-disp16")
       (attrs PCREL-ADDR RELOC)
       (word-offset 16)
       (word-length 16)
       (start 15)
       (length 16)
       (mode INT)
       (encode (value pc) (sra WI (sub WI value pc) (const 2)))
       (decode (value pc) (add WI (sll WI value (const 2)) pc))
     )

   If we didn't use `.splice', and instead just wrote:

     (define-pmacro (bad-dwf x-name x-comment x-attrs
                             x-word-offset x-word-length x-start x-length
                             x-mode x-encode x-decode)
       "Define a field including its containing word."
       (define-ifield
         (name x-name)
         (comment x-comment)
         (attrs x-attrs)
         (word-offset x-word-offset)
         (word-length x-word-length)
         (start x-start)
         (length x-length)
         (mode x-mode)
         (encode x-encode)
         (decode x-decode)
         )
     )

   Then that would expand to the following, which is incorrect:

     (define-ifield
       (name f-disp16)
       (comment "f-disp16")
       (attrs (PCREL-ADDR RELOC))
       (word-offset 16)
       (word-length 16)
       (start 15)
       (length 16)
       (mode INT)
       (encode ((value pc) (sra WI (sub WI value pc) (const 2))))
       (decode ((value pc) (add WI (sll WI value (const 2)) pc)))
     )

   Note the extra level of parentheses in the `attrs', `encode', and
`decode' fields.


File: cgen.info,  Node: Interactive development,  Next: Doing an opcodes port,  Prev: Writing a CPU description file,  Up: Porting

5.5 Interactive development
===========================

The normal way(1) of writing a CPU description file involves starting
Guile and developing the .CPU file interactively.  The basic steps are:

  1. Run `guile'.

  2. `(load "dev.scm")'

  3. Load application, e.g. `(load-opc)' or `(load-sim)'

  4. Load CPU description file, e.g. `(cload #:arch "cpu/m32r.cpu")'

  5. Run generators until output looks reasonable, e.g. `(cgen-opc.c)'

   To assist in the development process and to cut down on some typing,
`dev.scm' looks for `$HOME/.cgenrc' and, if present, loads it.  Typical
things that `.cgenrc' contains are definitions of procedures that
combine steps 3 and 4 above.

   Example:

     (define (m32r-opc)
       (load-opc)
       (cload #:arch "cpu/m32r.cpu")
     )
     (define (m32r-sim)
       (load-sim)
       (cload #:arch "cpu/m32r.cpu" #:options "with-scache with-profile=fn")
     )
     (define (m32rbf-sim)
       (load-sim)
       (cload #:arch "cpu/m32r.cpu" #:machs "m32r" #:options "with-scache with-profile=fn")
     )
     (define (m32rxf-sim)
       (load-sim)
       (cload #:arch "cpu/m32r.cpu" #:machs "m32rx" #:options "with-scache with-profile=fn")
     )

   CPU description files are loaded into an interactive guile session
with `cload'.  The syntax is:

     (cload #:arch "cpu-file-path"
            [#:machs "mach-list"]
            [#:isas "isa-list"]
            [#:options "option-list"]
            [#:trace "trace-list"]
            [#:diag "diagnostic-list"])

   Only the `#:arch' argument is mandatory.

   `cpu-file' is the path to the `.cpu' file.

   `mach-list' is a comma separated string of machines to keep.

   `isa-list' is a comma separated string of isas to keep.

   `options' is a space separated string of options for the application.
What the acceptable values are depends on the application.

   `trace' is a comma separated string of tracing options.  *Note t::.

   `diag' is a comma separated string of diagnostic options.  *Note w::.

   ---------- Footnotes ----------

   (1) Normal for some anyway, certainly each person will have their
own preference.


File: cgen.info,  Node: Doing an opcodes port,  Next: Doing a GAS port,  Prev: Interactive development,  Up: Porting

5.6 Doing an opcodes port
=========================

The best way to begin a port is to take an existing one (preferably one
that is similar to the new port) and use it as a template.

  1. Run `guile'.

  2. `(load "dev.scm")'. This loads in a set of interactive development
     routines.

  3. `(load-opc)'. Load the opcodes support.

  4. Edit your `cpu/$arch.cpu' and `cpu/$arch.opc' files.
        * The `.cpu' file is the main description file.

        * The `.opc' file provides additional C support code.

  5. `(cload #:arch "cpu/$arch.cpu")'

  6. `(set-opc-file-path! "cpu/$arch.opc")'

  7. Run each of:
        * `(cgen-desc.h)'

        * `(cgen-desc.c)'

        * `(cgen-opc.h)'

        * `(cgen-opc.c)'

        * `(cgen-ibld.in)'

        * `(cgen-asm.in)'

        * `(cgen-dis.in)'

        * `(cgen-opinst.c)' - [optional]

  8. Repeat steps 4, 5 and 6 until the output looks reasonable.

  9. Add dependencies to `opcodes/Makefile.am' to generate the eight
     opcodes files (use the M32R port as an example).

 10. Run `make dep' from the `opcodes' build directory.

 11. Run `make all-opcodes' from the top level build directory.


File: cgen.info,  Node: Doing a GAS port,  Next: Building a GAS test suite,  Prev: Doing an opcodes port,  Up: Porting

5.7 Doing a GAS port
====================

A GAS CGEN port is essentially no different than a normal port except
that the CGEN opcode table is used, and there are extra supporting
routines available in `gas/cgen.[ch]'.  As always, a good way to get
started is to take the M32R port as a template and go from there.

   The important CGEN-specific things to keep in mind are:

   * Several support routines are provided by `gas/cgen.c'.  Some must
     be used, others are available to use if you want to (in general
     they should be used unless it's not possible).

        * `gas_cgen_init_parse'
             - Call from `md_assemble' before doing anything
                           else.

             - Must be used.


        * `gas_cgen_record_fixup'
             - Cover function to `fix_new'.


        * `gas_cgen_record_fixup_exp'
             - Cover function to `fix_new_exp'.


        * `gas_cgen_parse_operand'
             - Callback for opcode table based parser, set in
                            `md_begin'.


        * `gas_cgen_finish_insn'
             - After parsing an instruction, call this to add the
                                instruction to the frag and queue any
               fixups.


        * `gas_cgen_md_apply_fix'
             - Provides basic `md_apply_fix' support.

             - `#define md_apply_fix
               gas_cgen_md_apply_fix' if you're able to use
                          it.


        * `gas_cgen_tc_gen_reloc'


             - Provides basic `tc_gen_reloc' support in function.

             - `#define tc_gen_reloc gas_cgen_tc_gen_reloc'
                          if you're able to use it.


   * `md_begin' should contain the following (plus anything else you
     want of course):

            /* Set the machine number and endianness.  */
            gas_cgen_opcode_desc =
              <arch>_cgen_cpu_open (CGEN_CPU_OPEN_MACHS,
                                    0 /* mach number */,
                                    CGEN_CPU_OPEN_ENDIAN,
                                    (target_big_endian
                                      ? CGEN_ENDIAN_BIG
                                      : CGEN_ENDIAN_LITTLE),
                                    CGEN_CPU_OPEN_END);

            <arch>_cgen_init_asm (gas_cgen_opcode_desc);

            /* This is a callback from cgen to gas to parse operands.  */
            cgen_set_parse_operand_fn (gas_cgen_opcode_desc, gas_cgen_parse_operand);

   * `md_assemble' should contain the following basic framework:

          {
            const CGEN_INSN *insn;
            char *errmsg;
            CGEN_FIELDS fields;
          #if CGEN_INT_INSN_P
            cgen_insn_t buffer[CGEN_MAX_INSN_SIZE / sizeof (CGEN_INSN_INT)];
          #else
            char buffer[CGEN_MAX_INSN_SIZE];
          #endif

            gas_cgen_init_parse ();

            insn = m32r_cgen_assemble_insn (gas_cgen_opcode_desc, str,
                                            &fields, buffer, &errmsg);

            if (! insn)
              {
                as_bad (errmsg);
                return;
              }

            gas_cgen_finish_insn (insn, buffer, CGEN_FIELDS_BITSIZE (&fields),
               relax_p, /* non-zero to allow relaxable insns */
               result); /* non-null if results needed for later */
          }



File: cgen.info,  Node: Building a GAS test suite,  Next: Doing a simulator port,  Prev: Doing a GAS port,  Up: Porting

5.8 Building a GAS test suite
=============================

CGEN can also build the template for test cases for all instructions.
In some cases it can also generate the actual instructions.  The result
is then assembled, disassembled, verified, and checked into CVS.
Further changes are usually done by hand as it's easier.  The goal here
is to save the enormous amount of initial typing that is required.

  1. `cd' to the CGEN build directory

  2. `make gas-test'

     At this point two files have been created in the CGEN build
     directory: `gas-allinsn.exp' and `gas-build.sh'.  The
     `gas-build.sh' script normally requires one command line argument:
     the location of your `gas' build directory.  If this argument is
     omitted, the script searches in `../gas' automatically.

  3. Copy `gas-allinsn.exp' to
     `toplevel/gas/testsuite/gas/<arch>/allinsn.exp'.

  4. `sh gas-build.sh'

     At this point directory tmpdir contains two files: `allinsn.s' and
     `allinsn.d'.  File `allinsn.d' usually needs a bit of massaging.

  5. Copy `tmpdir/allinsn.[sd]' to `toplevel/gas/testsuite/gas/<arch>'

  6. Run `make check' in the `gas' build directory and massage things
     until you're satisfied the files are correct.

  7. Check files into CVS.

   At this point further additions/modifications are usually done by
hand.


File: cgen.info,  Node: Doing a simulator port,  Next: Building a simulator test suite,  Prev: Building a GAS test suite,  Up: Porting

5.9 Doing a simulator port
==========================

_NOTE:_ This section applies to GDB simulators, not SID simulators
(*note SID Simulator::).

   The same basic procedure for opcodes porting applies here.

   Simulator ports consist of four pieces:

   * configury

     You'll have to write `Makefile.in' and `configure.ac'.  It's
     easiest to simply take an existing one as boilerplate and hack it.

   * things common to all simulators

     Directory `sim/common' in the simulator tree consists of various
     things the simulators use.  You probably won't have to hack on
     these files, but you might if your target has needs something new.

   * main loop

     CGEN simulators generate source code for their main loop from a
     shell script, named by convention `mloop.in'.  It's easiest to
     take an existing one as boilerplate and hack it.

   * generated files

     The CGEN generated files.


* Menu:

* Simulator files::                   Notes on the various files
* Interactive simulator development:: Testing the generated files


File: cgen.info,  Node: Simulator files,  Next: Interactive simulator development,  Up: Doing a simulator port

5.9.1 Simulator files
---------------------

The following additional files are also needed. These live in the
`sim/<arch>' directory. Administrivia files like `configure.in' and
`Makefile.in' are omitted.

   * `sim-main.h'

     Main include file required by the "common" (`sim/common') support,
     and by each target's `.c' file.  This file includes the relevant
     other headers.  The order is fairly important.  `m32r/sim-main.h'
     is a good starting point.

     `sim-main.h' also defines several types:

        - `_sim_cpu' - a struct containing all state for a particular
          CPU.

        - `sim_state' - contains all state of the simulator.  A
          `SIM_DESC' (which is the result of sim_open and is akin to a
          file descriptor) points to one of these.

        - `sim_cia' - type of an instruction address.  For CGEN this is
          generally "word mode", in GCC parlance.

     `sim-main.h' also defines several macros:

        - `CIA_GET(cpu)' - return "cia" of the CPU

        - `CIA_SET(cpu,cia)' - set the "cia" of the CPU

     "cia" is short for "current instruction address".

     The definition of `sim_state' is fairly simple.  Just copy the M32R
     case.  The definition of `_sim_cpu' is not simple, so pay
     attention.  The complexity comes from trying to create a "derived
     class" of `sim_cpu' for each CPU family.  What is done is define a
     different version of `sim_cpu' in each CPU family's set of files,
     with a common "base class" structure "leading part" for each
     `sim_cpu' definition used by non-CPU-family specific files.  The
     way this is done is by defining `WANT_CPU_<CPU-FAMILY-NAME>' at the
     top of CPU family specific files. The definition of `_sim_cpu' is
     then:

          	struct _sim_cpu {
          	  /* sim/common CPU base */
          	  sim_cpu_base base;
          	  /* Static parts of CGEN.  */
          	  CGEN_CPU cgen_CPU;
          	#if defined (WANT_CPU_CPUFAM1)
          	  CPUFAM1_CPU_DATA CPU_data;
          	#elif defined (WANT_CPU_CPUFAM2)
          	  CPUFAM2_CPU_DATA CPU_data;
          	#endif
          	};

   * `tconfig.in'

     This file predates `sim-main.h' and was/is intended to contain
     macros that configure the simulator sources.

        * `SIM_HAVE_MODEL' - enable `common/sim-model.[ch]' support.

        * `SIM_HANDLES_LMA' - makes `sim-hload.c' do the right thing.

        * `WITH_SCACHE_PBB' - define this to 1 if using pbb scaching.

   * `<arch>-sim.h'

     This file predates `sim-main.h' and contains miscellaneous macros
     and definitions used by the simulator.

   * `mloop.in'

     This file contains code to implement the fetch/execute process.
     There are various ways to do this, and several are supported.
     Which one to choose depends on the environment in which the CPU
     will be used.  For example when executing a program in a
     single-CPU environment without devices, most or all available
     cycles can be devoted to simulation of the target CPU.  However,
     in an environment with devices or multiple cpus, one may wish the
     CPU to execute one instruction then relinquish control so a device
     operation may be done or an instruction can be simulated on a
     second cpu.  Efficient techniques for the former aren't
     necessarily the best for the latter.

     Three versions are currently supported:

       1. simple - fetch/decode/execute one insn

       2. scache - same as simple but results of decoding are cached

       3. pbb - same as scache but several insns are handled each
          iteration pbb stands for pseudo basic block.

     This file is processed by `common/genmloop.sh' at build time. The
     result is two files: `mloop.c' and `eng.h'.

   * `sim-if.c'

     By convention this file contains `sim_open', `sim_close',
     `sim_create_inferior', `sim_do_command'.  These functions can live
     in any file of course.  They're here because they're the parts of
     the `remote-sim.h' interface that aren't provided by the common
     directory.

   * `<cpufam>.c'

     By convention this file contains register access and model support
     functions for a CPU family (the name of this file is misnamed in
     the M32R case).  The register access functions implement the
     `sim_fetch_register' and `sim_store_register' interface functions
     (named `<cpufam>_{fetch,store}_register'), and support code for
     register get/set rtl.  The model support functions implement the
     before/after handlers (functions that handle tracing/profiling) and
     timing for each function unit.

   * Other files

     The M32R port has two other handwritten files: `devices.c' and
     `traps.c'.  How you wish to organize this is up to you.


File: cgen.info,  Node: Interactive simulator development,  Prev: Simulator files,  Up: Doing a simulator port

5.9.2 Interactive simulator development
---------------------------------------

When ready to generate the simulator files,

  1. Run `guile'.

  2. `(load "dev.scm")'

  3. `(load-sim)'

  4. Edit your `cpu/$arch.cpu' file.

  5. `(cload #:arch "cpu/$arch.cpu")'

  6. Run each of:


        * `(cgen-arch.h)'

        * `(cgen-arch.c)'

        * `(cgen-cpuall.h)'

  7. Repeat steps 4,5,6 until the output looks reasonable.

  8. Edit your `cpu/<arch>.cpu' file.

  9. `(cload #:arch "cpu/$arch.cpu" #:machs "mach1[,mach2[,...]]")'

 10. Run each of:


        * `(cgen-cpu.h)'

        * `(cgen-cpu.c)'

        * `(cgen-decode.h)'

        * `(cgen-decode.c)'

        * `(cgen-semantics.c)'

        * `(cgen-sem-switch.c)' - only if using a switch()
            version of semantics.

        * `(cgen-model.c)'

 11. Repeat steps 8, 9 and 10 until the output looks reasonable.


File: cgen.info,  Node: Building a simulator test suite,  Prev: Doing a simulator port,  Up: Porting

5.10 Building a simulator test suite
====================================

CGEN can also build the template for test cases for all instructions.
In some cases it can also generate the actual instructions (1).  The
result is then verified and checked into CVS.  Further changes are
usually done by hand as it's easier.  The goal here is to save the
enormous amount of initial typing that is required.

  1. `cd' to the CGEN build directory

  2. `make sim-test ISA=<arch>'

     At this point two files have been created in the CGEN build
     directory: `sim-allinsn.exp' and `sim-build.sh'.

  3. Copy `sim-allinsn.exp' to
     `toplevel/sim/testsuite/sim/<arch>/allinsn.exp'.

  4. `sh sim-build.sh'

     At this point a new subdirectory called `tmpdir' will be created
     and will contain one test case for each instruction.  The
     framework has been filled in but not the actual test case.  It's
     handy to write an "include file" containing assembler macros that
     simplify writing test cases.  See
     `toplevel/sim/testsuite/sim/m32r/testutils.inc' for an example.

  5. write testutils.inc

  6. finish each test case

  7. copy `tmpdir/*.cgs' to `toplevel/sim/testsuite/sim/<arch>'

  8. run `make check' in the sim build directory and massage things
     until you're satisfied the files are correct

  9. Check files into CVS.

At this point further additions/modifications are usually done by hand.

   ---------- Footnotes ----------

   (1) Although this hasn't been implemented yet.


File: cgen.info,  Node: Opcodes,  Next: Simulation,  Prev: Porting,  Up: Top

6 Opcodes support
*****************

Opcodes support comes in the form of machine generated opcode tables as
well as supporting routines.

* Menu:

* Generated files::                 List of generated files
* The .opc file::                   Target specific C code
* Special assembler parsing needs:: Support for unusual syntax


File: cgen.info,  Node: Generated files,  Next: The .opc file,  Up: Opcodes

6.1 Generated files
===================

The basic interface is defined by `include/opcode/cgen.h' which is
included by the machine generated `<arch>-desc.h'.  `opcode/cgen.h' can
stand on its own for the target independent stuff, but to get target
specific parts of the interface use `<arch>-desc.h'.

   The generated files are:

`<arch>-desc.h'
     Defines macros, enums, and types used to describe the chip.

`<arch>-desc.c'
     Tables of various things describing the chip.  This does not
     include assembler syntax nor semantic information.

`<arch>-ibld.c'
     Routines for constructing and deconstructing instructions.

`<arch>-opc.h'
     Declarations necessary for assembly/disassembly that aren't used
     elsewhere and thus left out of `<arch>-desc.h'.

`<arch>-opc.c'
     Assembler syntax tables.

`<arch>-asm.c'
     Assembler support routines.

`<arch>-dis.c'
     Disassembler support routines.

`<arch>-opinst.c'
     Operand instance tables.  These describe which hardware elements
     are read and which are written for each instruction.  This file
     isn't generated for all architectures, only ones that can make use
     of the data.  For example the M32R uses them to emit warnings if
     the output of one parallel instruction is the input of another,
     and to control creating parallel instructions during optimizing
     assembly.


File: cgen.info,  Node: The .opc file,  Next: Special assembler parsing needs,  Prev: Generated files,  Up: Opcodes

6.2 The .opc file
=================

Files with suffix `.opc' (e.g. `m32r.opc') contain target specific C
code that accompanies the cpu description file.  The `.opc' file is
split into 4 sections:

   - opc.h

     This section contains additions to the generated `$target-opc.h'
     file.

     Typically defined here are these macros:

        * #define CGEN_DIS_HASH_SIZE N

          Specifies the size of the hash table to use during
          disassembly.  A hash table is built of the selected mach's
          instructions in order to speed up disassembly.

        * #define CGEN_DIS_HASH(buffer, value)

          Given BUFFER, a pointer to the instruction being disassembled
          and VALUE, the value of the instruction as a host integer,
          return an index into the hash chain for the instruction.  The
          result must be in the range 0 to CGEN_DIS_HASH_SIZE-1.

          VALUE is only usable if all instructions fit in a portable
          integer (32 bits).

          N.B. The result must depend on opcode portions of the
          instruction only.  Normally one wants to use between 6 and 8
          bits of opcode info for the hash table.  However, some
          instruction sets don't use the same set of bits for all
          insns.  Certainly they'll have at least one opcode bit in
          common with all insns, but beyond that it can vary.  Here's a
          possible definition for sparc.

               #undef CGEN_DIS_HASH_SIZE
               #define CGEN_DIS_HASH_SIZE 256
               #undef CGEN_DIS_HASH
               extern const unsigned int sparc_cgen_opcode_bits[];
               #define CGEN_DIS_HASH(buffer, insn) \
               ((((insn) >> 24) & 0xc0) \
                | (((insn) & sparc_cgen_opcode_bits[((insn) >> 30) & 3]) >> 19))

          `sparc_cgen_opcode_bits' would be defined in the `asm.c'
          section as

               /* It is important that we only look at insn code bits
                  as that is how the opcode table is hashed.
                  OPCODE_BITS is a table of valid bits for each of the
                  main types (0,1,2,3).  */
               const unsigned int sparc_cgen_opcode_bits[4] = {
                 0x01c00000, 0x0, 0x01f80000, 0x01f80000
               };

   - opc.c

   - asm.c

     This section contains additions to the generated `$target-asm.c'
     file.  Typically defined here are functions used by operands with
     a `parse' define-operand handler spec.

   - dis.c

     This section contains additions to the generated `$target-dis.c'
     file.

     Typically defined here these macros:

        * #define CGEN_PRINT_NORMAL(cd, info, value, attrs, pc, length)

        * #define CGEN_PRINT_ADDRESS(cd, info, value, attrs, pc, length)

        * #define CGEN_PRINT_INSN function_name

        * #define CGEN_BFD_ARCH bfd_arch_<name>

        * #define CGEN_COMPUTE_ISA(info)



File: cgen.info,  Node: Special assembler parsing needs,  Prev: The .opc file,  Up: Opcodes

6.3 Special assembler parsing needs
===================================

Often parsing of assembly instructions requires more than what a
program-generated assembler can handle.  For example one version of an
instruction may only accept certain registers, rather than the entire
set.

   Here's an example taken from the `m32r' architecture.

   32 bit addresses are built up with a two instruction sequence: one to
load the high 16 bits of a register, and another to `or'-in the lower
16 bits.

     seth r0,high(some_symbol)
     or3  r0,r0,low(some_symbol)

   When assembling, special code must be called to recognize the `high'
and `low' pseudo-ops and generate the appropriate relocations.  This is
indicated by specifying a "parse handler" for the operand in question.
Here is the `define-operand' for the lower 16 bit operand.

     (define-operand
       (name ulo16)
       (comment "16 bit unsigned immediate, for low()")
       (attrs)
       (type h-ulo16)
       (index f-uimm16)
       (handlers (parse "ulo16"))
     )

   The generated parser will call a function named `parse_ulo16' for
the immediate operand of the `or3' instruction.  The name of the
function is constructed by prepended "parse_" to the argument of the
`parse' spec.

     errmsg = parse_ulo16 (cd, strp, M32R_OPERAND_ULO16, &fields->f_uimm16);

   But where does one put the `parse_ulo16' function?  Answer: in the
`asm.c' section of `m32r.opc'.


File: cgen.info,  Node: Simulation,  Next: Writing an application,  Prev: Opcodes,  Up: Top

7 Simulation support
********************

Simulator support comes in the form of machine generated the
decoder/executer as well as the structure that records CPU state
information (i.e., registers).

   There are currently two simulators that use CGEN:

* Menu:

* GDB Simulator::
* SID Simulator::


File: cgen.info,  Node: GDB Simulator,  Next: SID Simulator,  Up: Simulation

7.1 GDB Simulator
=================

Several simulators in the GDB tree use CGEN.  These simulators use a
combination of the CGEN-generated files, common files in the sim/common
directory of GDB releases, and custom target-specific code.

   There are 3 architecture-wide generated files:

`arch.h'
     Definitions and declarations common to the entire architecture.

`arch.c'
     Tables and code common to the entire architecture, but which can't
     be put in the common area.

`cpuall.h'
     Pseudo base classes of various structures.

   Each "CPU family" has its own set of the following files:

`cpu.h'
     Definitions and declarations specific to a particular CPU family.

`cpu.c'
     Tables and code specific to a particular CPU family.

`decode.h'
     Decoder definitions and declarations.

`decode.c'
     Decoder tables and code.

`model.c'
     Tables and code for each model in the CPU family.

`semantics.c'
     Code to perform each instruction.

`sem-switch.c'
     Same as `semantics.c' but as one giant `switch' statement.

   Either or both of `semantics.c' and `sem-switch.c' may be provided,
it's up to the port to choose.  `semantics.c' is either to work with,
one function per instruction, but `sem-switch.c' uses a "computed goto"
switch and is thus provides faster simulation.

   _NOTE:_ The actual file names are up to the port.  The names of the
files listed here are the convention.  One reason to use different
names is if the port is simulating different architecture variants and
generates different files for each variant.

   A "CPU family" is an artificial creation to sort architecture
variants along whatever lines seem useful.  Additional hand-written
files must be provided.  *Note Porting::, for details.


File: cgen.info,  Node: SID Simulator,  Prev: GDB Simulator,  Up: Simulation

7.2 SID Simulator
=================

The SID simulator has its home page here: http://sourceware.org/sid/.
Please refer to it for documentation on SID.

   The CGEN-based simulators in SID live in directory
sid/component/cgen-cpu of the SID source tree.

   CGEN provides the instruction decoder and semantic routines.


File: cgen.info,  Node: Writing an application,  Next: Glossary,  Prev: Simulation,  Up: Top

8 Writing an application
************************

This chapter contains information for those wishing to write their own
CGEN application.

* Menu:

* File Layout::                 Organization of source files
* File Generation Process::     Workflow in cgen
* Coding Conventions::          Coding conventions
* Accessing Loaded Data::       Reading data from loaded .cpu files
* Arch Name References::        Architecture names in generated code
* String Building::             Building long strings and writing them out
* COS::                         Cgen's Object System


File: cgen.info,  Node: File Layout,  Next: File Generation Process,  Up: Writing an application

8.1 File Layout
===============

Source files in cgen are organized in a very specific way.(1)  It makes
it easy to find things.

   * top level file is cgen-<app>.scm

     The best way to create this file is to copy an existing
     application's file (e.g. cgen-opc.scm) and modify to suit.

   * file <app>.scm contains general app-specific utilities

   * other files are <app>-foo.scm

   * add entry to dev.scm (load-<app>)


   ---------- Footnotes ----------

   (1) As the number of source files grows the entire layout may be
changed, but until then this is how things are.


File: cgen.info,  Node: File Generation Process,  Next: Coding Conventions,  Prev: File Layout,  Up: Writing an application

8.2 File Generation Process
===========================

This is an overview of cgen workflow.

   * cgen is started with list of files to generate and code generation
     options

   * source code is loaded

        - application independent code is loaded if not compiled in

        - application specific code is loaded

          Currently app-specific code is never compiled in.  (1)

             - doesn't affect speed as much as application independent
               stuff

             - subject to more frequent changes

             - makes it easier to do application development if changes
               to .scm files are "ready to use"

   * ultimately procedure `cpu-load' is called which is the main driver
     for loading .cpu files

   * various data structures are initialized

   * data files are loaded

        - main <arch>.cpu file is loaded

          There is a #include-like mechanism for loading other files so
          big architectures can be broken up into several files.

          While the architecture description is being loaded, entries
          not requested are discarded.  This happens, for example, when
          building a simulator: there's no point in keeping
          instructions specific to a machine that is not being
          generated.  What to keep is based on the MACH and ISA
          attributes.

        - application specific data files are loaded

          e.g. <arch>.sim

   * builtin elements are created

   * each requested file is generated by calling cgen-<file> generator

     The output is written to the output file with
     `with-output-to-file' so the code must write to
     `(current-output-port)'.

     Some files require heavy duty processing of the cpu description.
     For example the simulator computes the instruction formats from the
     instruction field lists of each instruction.  This computation is
     deferred to each cgen-<file> procedure that needs it and must be
     explicitly requested by them.  The results are cached so this is
     only done once of course.

   * additional processing for some opcodes files

     Several opcodes files are built from three sources.

        - generated code

        - section in <arch>.opc file

          It's not appropriate to put large amounts of C (or perhaps
          any C) in cgen description files, yet some things are best
          expressed in some other language (e.g. assembler/disassembler
          operand parsing/printing).

        - foo.in file

          It seems cleaner to put large amounts of
          non-machine-generated C in separate files from code generator.


   ---------- Footnotes ----------

   (1) This dates from a time when CGEN supported being compiled with
Hobbit.  That support is gone, though something else may take its place.


File: cgen.info,  Node: Coding Conventions,  Next: Accessing Loaded Data,  Prev: File Generation Process,  Up: Writing an application

8.3 Coding Conventions
======================

   * unless definition occupies one line, final trailing parenthesis is
     on a line by itself beginning in column one

   * definitions internal to a source file begin with '-'

   * global state variables are named *foo-bar* [FIXME: current code
     needs updating]

   * avoid uppercase, except for constants (e.g. `*UNSPECIFIED*')

   * procedures that return a boolean result end in '?'

   * procedures that modify something end in '!'

   * classes are named <name>


File: cgen.info,  Node: Accessing Loaded Data,  Next: Arch Name References,  Prev: Coding Conventions,  Up: Writing an application

8.4 Accessing Loaded Data
=========================

Each kind of description file entry (defined with `define-foo') is
recorded in an object of class <foo>.(1) All the data is collected
together in an object of class <arch>.  (2)

   Data for the currently selected architecture is obtained with several
access functions.

       (current-arch-name)
       - return symbol that is the name of the arch
       - this is the name specified with `define-arch'

       (current-arch-comment)
       - return the comment specified with `define-arch'

       (current-arch-atlist)
       - return the attributes specified with `define-arch'

       (current-arch-default-alignment)
       - return a symbol indicated the default alignment
         - one of aligned, unaligned, forced

       (current-arch-insn-lsb0?)
       - return a #t if the least significant bit in a word is numbered 0
       - return a #f if the most significant bit in a word is numbered 0

       (current-arch-mach-name-list)
       - return a list of names (as symbols) of all machs in the architecture

       (current-arch-isa-name-list)
       - return a list of names (as symbols) of all isas in the architecture

       For most of the remaining elements, there are three main accessors:
       [foo is sometimes abbreviated]
         - current-foo-list - returns list of <foo> objects in the architecture
         - current-foo-add! - add a <foo> object to the architecture
         - current-foo-lookup - lookup the <foo> object based on its name

       <atlist>
       (current-attr-list)
       (current-attr-add!)
       (current-attr-lookup)

       <enum>
       (current-enum-list)
       (current-enum-add!)
       (current-enum-lookup)

       <keyword>
       (current-kw-list)
       (current-kw-add!)
       (current-kw-lookup)

       <isa>
       (current-isa-list)
       (current-isa-add!)
       (current-isa-lookup)

       <cpu>
       (current-cpu-list)
       (current-cpu-add!)
       (current-cpu-lookup)

       <mach>
       (current-mach-list)
       (current-mach-add!)
       (current-mach-lookup)

       <model>
       (current-model-list)
       (current-model-add!)
       (current-model-lookup)

       <hardware>
       (current-hw-list)
       (current-hw-add!)
       (current-hw-lookup)

       <ifield>
       (current-ifld-list)
       (current-ifld-add!)
       (current-ifld-lookup)

       <operand>
       (current-op-list)
       (current-op-add!)
       (current-op-lookup)

       <insn>
       (current-insn-list)
       (current-insn-add!)
       (current-insn-lookup)

       <macro-insn>
       (current-minsn-list)
       (current-minsn-add!)
       (current-minsn-lookup)

       (current-ifmt-list)
       - return list of computed <iformat> objects

       (current-sfmt-list)
       - return list of computed <sformat> objects

       [there are a few more to be documented, not sure they'll remain as is]

   ---------- Footnotes ----------

   (1) not true for <arch> but will be RSN

   (2) modes aren't recorded here, should they be?


File: cgen.info,  Node: Arch Name References,  Next: String Building,  Prev: Accessing Loaded Data,  Up: Writing an application

8.5 Arch Name References
========================

To simplify writing code generators, system names can be specified with
fixed strings rather than having to compute them.  The output is
post-processed to convert the strings to the actual names.  Upper and
lower case names are supported.

   * For the architecture name use @arch@, @ARCH@.

   * For the cpu family name use @cpu@, @CPU@.

   * For the prefix use @prefix@, @PREFIX@.

   The `prefix' notion is to segregate different code for the same cpu
family.  For example, this is used to segregate the ARM ISA from the
Thumb ISA.


File: cgen.info,  Node: String Building,  Next: COS,  Prev: Arch Name References,  Up: Writing an application

8.6 String Building
===================

Output generation uses a combination of writing text out as it is
computed and building text for later writing out.

   The top level file generator uses `string-write'.  It takes
string-lists and thunks as arguments and writes each argument in turn
to stdout.  String-lists are lists of strings (nested arbitrarily
deep).  It's cheaper to `cons' long strings together than to use
`string-append'.  Thunks return string-lists to write out, but isn't
computed until all preceding arguments to `string-write' have been
written out.  This allows deferring building up of large amounts of
text until it needs to be.

   The main procedures for building strings and writing them out are:

   * (string-write string-list-or-thunk1 string-list-or-thunk2 ...)

     Loops over arguments writing them out in turn.

   * (string-write-map proc string-list-or-thunk-list)

     Apply proc to each element in string-list-or-thunk-list and write
     out the result.

   * (string-list arg1 arg2 ...)

     Return list of arguments.  This is identical to `list' except it
     is intended to take string-lists as arguments.

   * (string-list-map proc arg-list)

     Return list of `proc' applied to each element of `arg-list'.  This
     is identical to `map' except it is intended to take strings as
     arguments.

   * (string-append string1 string2 ...)

     For small arguments it's just as well to use `string-append'.
     This is a standard Scheme procedure.  The output is also easier to
     read when developing interactively.  And some subroutines are used
     in multiple contexts including some where strings are required, so
     sometimes you have to use `string-append'.



File: cgen.info,  Node: COS,  Prev: String Building,  Up: Writing an application

8.7 COS
=======

COS is CGEN's Object System.  It's a simple OO system for Guile that
was written to provide something useful until Guile had its own.  COS
will be replaced with GOOPs if the Scheme implementation of CGEN is
kept.

   The pure Scheme implementation of COS uses vectors to record objects
and classes.

   A complete list of user-visible functions is at the top of `cos.scm'.

   Here is a list of the frequently used ones.

   * (class-make name parent-name-list element-list method-list)

     Use `class-make' to define a class.

          name: symbol, <name-of-class>
          parent-name-list: list of symbols, names of each parent class
          element-list: list of either symbols or (symbol . initial-value)
          method-list: list of (symbol . lambda)

     The result is the class's definition.  It is usually assigned to a
     global variable with same name as class's name.  Current cgen code
     always does this.  It's not a requirement but it is convention.

   * (new <class-name>)

     Create a new object with `new'.  `<class-name>' is typically the
     global variable that recorded the results of `class-make'.  The
     result is a new object of the requested class.  Class elements
     have either an "undefined" value or an initial value if one was
     specified when the class was defined.

   * (define-getters class-name prefix element-list)

     Elements (aka members) are read/written with "accessors".  Read
     accessors are defined with `define-getters', which creates one
     procedure for each element, each defined as `(prefix-element-name
     object)'.

     This is a macro so don't quote anything.

   * (define-setters class-name prefix element-list)

     Write accessors are defined with `define-setters', which creates
     one procedure for each element, each defined as
     `(prefix-set-element-name! object new-value)'.

     This is a macro so don't quote anything.

   * (elm-get object elm-name)

     This can only be used in method definitions (blech, blah blah
     blah).

   * (elm-set! object elm-name new-value)

     This can only be used in method definitions (blech, blah blah
     blah).

   * (send object method-name arg1 arg2)

     Invoke method `method-name' on `object'.

     The convention is to put this in a cover fn:
     `(class-name-method-name object arg1 arg2)'.

   * (send-next object method-name arg1 arg2)

     Same as `send' except only usable in methods and is used to invoke
     the method in the parent class.

   * (make object . args)

     One standard way to create a new object is with `make'.  It is a
     wrapper, defined as

          (define (make object . args)
            (apply send (cons (new object) (cons 'make! args)))
          )

   * (vmake class . args)

     The other standard way to create objects is with `vmake'.

     `args' is a list of option names and arguments.

     ??? Not completely implemented yet.

   * (method-make! class method-name lambda)

     The normal way of creating methods is to use `method-make!', not
     define them with the class.  It's just easier to define them
     separately.

   * (method-make-virtual! class method-name lambda)

     Create virtual methods created with `method-make-virtual!'.

   * (method-make-forward! class elm-name methods) -> unspecified

     Forwarding a method invocation on one object to another is
     extremely useful so some utilities have been created to simplify
     creating forwarding methods.

     `methods' is a list of method names.  A method is created for each
     one that forwards the method onto the object contained in element
     ELM-NAME.

   * (method-make-virtual-forward!)

     Same as method-make-forward! except that it creates virtual
     methods.



File: cgen.info,  Node: Glossary,  Next: Miscellaneous notes,  Prev: Writing an application,  Up: Top

9 Glossary
**********

arch
     This is the overall architecture.  It is the same as BFD's use of
     _arch_.

isa
     Acronym for Instruction Set Architecture.

mach
     This is a variant of the architecture, short for machine.  It is
     essentially the same as BFD's use of _mach_.

cpu family
     A group of related mach's.  Simulator support is organized along
     "cpu family" lines to keep related machs together under one roof to
     simplify things.  The organization is semi-arbitrary and is up to
     the programmer.

model
     An implementation of a mach.  It is essentially akin to the
     argument to `-mtune=' in SPARC GCC (and other GCC ports).

ifield
     An instruction field.

iformat
     An instruction format, as specified by the instruction's fields.

sformat
     An instruction semantic format.  This is different from `iformat'.
     For example, if an operand is referred to in one mode by one
     instruction and in a different mode by another instruction, then
     these two insns would have different sformats even if they have
     the same iformat.

insn
     An instruction.



File: cgen.info,  Node: Miscellaneous notes,  Next: Credits,  Prev: Glossary,  Up: Top

10 Miscellaneous notes
**********************

This chapter is a repository of miscellaneous notes that belong
elsewhere or nowhere.  They're here because I want them written down,
for now anyway, and I'm not sure where else to put them.  There may be
duplication here with things elsewhere in the docs.  I'm not bothering
to ensure there isn't.  It's better to have things written down twice
than not at all.  If there is a conflict between notes here and
elsewhere, check the chronology.  I may have changed my mind.  If not,
the situation may be complicated and I don't have a strong opinion on
what's right.  No claim is made that these notes represent my complete
opinion.  (Hmmm... lessee what other caveats I can throw in here ... :-)

* Menu:

* Description language notes::
* CGEN architecture notes::
* COS notes::
* RTL notes::
* Guile implementation notes::
* Code generation notes::
* Machine generated files notes::
* Implementation language notes::


File: cgen.info,  Node: Description language notes,  Next: CGEN architecture notes,  Up: Miscellaneous notes

10.1 Description language notes
===============================

   - timing support

     The current implementation of timing (aka pipeline, function
     units, etc.)  support is a quick hack in order to achieve useful
     numbers out of the simulator.  It is intended to be replaced with
     something a lot more sophisticated.  Remember to keep in mind
     cgen's goal of application independence when designing the new
     version.  For example, it must handle things like code scheduling
     in a compiler (where speed of analysis is not critical) to
     scheduling in a dynamic compiler (where speed of analysis is
     critical).  It must also handle semi-accurate to fully-accurate
     cycle counting in simulators (where the former might trade off
     accuracy for speed which one wouldn't do in the latter, assuming
     there is a trade-off to be made).  It must also handle the
     representation and handling of pipelines with program visible
     hazards.

   - organization of cpu description

     One thing that may not be apparent is that the description language
     doesn't preclude one item (say an insn) from having its definition
     spread over several files.  One example would be to leave the
     timing elements unspecified in the "main" entry of an insn, and
     then have a machine-specific file providing timing
     characteristics, etc.

     One can even leave the semantics to be defined elsewhere.  The `='
     insn format prefix is not currently used very much (no need).  It
     might also need better documentation.

     A possible break-up of an item's description into several files
     should be generally supported (where reasonable).



File: cgen.info,  Node: CGEN architecture notes,  Next: COS notes,  Prev: Description language notes,  Up: Miscellaneous notes

10.2 CGEN architecture notes
============================

   - compiled form of description in libcgen

     The current compiled form of the cpu description has been focused
     on two applications: opcodes and simulator.  No doubt there are
     things present that will present problems to future applications.
     One thing on the todo list has been to record semantics with the
     compiled form, probably as bytecode.  Maybe it would make sense to
     record the entire cpu description as a kind of bytecode.  This
     would allow apps to instantiate it for the task at hand as they
     please.

   - function-style attributes

     Attributes currently only support static (compile-time computed)
     notions.  They should also support run-time computed values.  The
     way to do this is to record such attributes as bytecode and lazily
     (or not lazily) evaluate them at runtime, perhaps caching the
     results.  It might make sense to record all attributes this way
     (though I currently don't think so).

   - importance of description language

     When hacking on cgen, the description language takes priority over
     implementation.  That cannot be stressed enough.  When faced with
     choices of what to do, put the elegance, maintainability, and
     application independence of the description language first.
     Implementation will almost always take shortcuts due to
     application specific requirements.  Theoretically the description
     language won't have to; at least that's where the effort in
     application independence should be put.



File: cgen.info,  Node: COS notes,  Next: RTL notes,  Prev: CGEN architecture notes,  Up: Miscellaneous notes

10.3 COS notes
==============

   - elm-xget, elm-xset

     These procedures are quick hacks and should be avoided.  Existing
     uses should be replaced.  Where they're used it's either because
     of laziness or because I wasn't sure whether I wanted to allow
     global access to the element, so using an easily grep-able hack
     let's me find them and revisit them.



File: cgen.info,  Node: RTL notes,  Next: Guile implementation notes,  Prev: COS notes,  Up: Miscellaneous notes

10.4 RTL notes
==============

   - Where's strict_lowpart?  Where's foo?

     Elements of gcc's rtl like strict_lowpart, pre_inc, etc. aren't in
     cgen's rtl only because thus far there hasn't been a compelling
     need for them.  When there is a compelling need they'll be added.

   - boolean values

     Sometimes #f/#t is used for boolean values.  However the "boolean"
     mode `BI' has values 0 and 1.  Which one is in use is context
     dependent.  Not sure there is a problem but it should be revisited.

   - #f to denote "unspecified" values

     Sometimes () is used to specify "unspecified" values.  Other times
     #f is used.  Should standardize in #f.

   - ifield assertions

     Perhaps these should be renamed to "constraints".
     "ifield-assertion" sounds clumsy.



File: cgen.info,  Node: Guile implementation notes,  Next: Code generation notes,  Prev: RTL notes,  Up: Miscellaneous notes

10.5 Guile implementation notes
===============================

   - Remaining todo is to complete switchover from "errtxt" (a string)
     in .cpu file reader support to "context" (a <context> object).

   - Remaining todo is to complete switchover of naming functions from
     "prefix:function" to "prefix-function".  One reasonable naming
     style is "prefix-verb-noun".  I like it.

   - Slib uses "prefix:foo" for "internal" routines.  Maybe that would
     be a better choice than the current "-prefix-foo" style.



File: cgen.info,  Node: Code generation notes,  Next: Machine generated files notes,  Prev: Guile implementation notes,  Up: Miscellaneous notes

10.6 Code generation notes
==========================

   - foo



File: cgen.info,  Node: Machine generated files notes,  Next: Implementation language notes,  Prev: Code generation notes,  Up: Miscellaneous notes

10.7 Machine generated files notes
==================================

   - In the end I think the best thing is to build the machine
     generated files when the tools themselves are built (same as gcc's
     gen* -> insn* files).



File: cgen.info,  Node: Implementation language notes,  Prev: Machine generated files notes,  Up: Miscellaneous notes

10.8 Implementation language notes
==================================

In the end I think the implementation language (or the Guile
implementation) will have to change.  If one compares the speed of
gcc's gen* file generators vs cgen's, and one envisions the day when
machine generated files are built at build time, then I think the user
community will require similar speed in file generation.  Guile isn't
fast enough.  And while Guile+Hobbit may be, for the one-time builder
the time taken to compile Hobbit, run it, and compile the result, will
appear to swamp any gains.  There is also the additional burden of
building Guile first (though with my preferred Guile implementation I'm
_hoping_ that wouldn't be a problem).

   The pragmatic choice is C.  Blech.

   A better choice would be C++ but then that would obviously place a
requirement on having a C++ compiler available in order to build
binutils, for example (assuming machine generated files are built at
build time).

   Java would also be a better implementation language than C [an
interesting experiment would be Kawa].  But it's worse as a pragmatic
choice than C++.

   My preferred choice is a small-and-fast subset of Guile that gets
distributed with binutils, gdb, etc.  IMO Guile is too bloated and
unmaintainable for the casual maintainer (hacking on its innards
requires too steep a learning curve, and is one that is easily slipped
back down should one step away from it for too long).  If those can be
fixed and the speed of cgen's file generation can be made acceptable,
then that is the path I would choose.

   In making the choice people need to look forward rather than look
backward.  We're finally switching the GNU tools to ANSI C.  If the
host doesn't provide an ANSI C compiler the user is expected to get one
(GCC).  Well, G++ is available on most if not all hosts of concern, so
in this day and age requiring C++ in order to build binutils isn't as
much of a burden as it use to be.  Cgen is a forward looking design.
At its heart is a goal to close no doors on future uses.  That's a
pretty lofty goal.  Forcing people to achieve that goal with C because
of pragmatic concerns is unjustifiable, IMO.

   Note that changing the "implementation language" does _not_ mean
Guile cannot or will not be used for various things!  I think Guile
should continue to be used for prototyping as well as certain
applications.


File: cgen.info,  Node: Credits,  Next: Index,  Prev: Miscellaneous notes,  Up: Top

11 Credits
**********

The following people, listed in alphabetical order, have contributed to
CGEN in their own way-thanks!  If you feel your name has been wrongly
omitted from this list, please contact one of the maintainers.

   - Dave Brolley

   - Andrew Cagney

   - Steve Chamberlain

   - Nick Clifton

   - Bob Cmelik

   - Frank Ch. Eigler

   - Ben Elliston

   - Matthew Green

   - Kim Knuttila

   - Greg McGary

   - Ken Raeburn

   - Ian Lance Taylor

   - Jim Wilson


File: cgen.info,  Node: Index,  Prev: Credits,  Up: Top

Index
*****

[index]
* Menu:

* .add:                                  .add.                (line   6)
* .and:                                  .and.                (line   6)
* .andif:                                .andif.              (line   6)
* .apply:                                Applying a pmacro to a list.
                                                              (line   6)
* .begin:                                A block of statements.
                                                              (line   6)
* .caar:                                 car/cdr.             (line   6)
* .cadr:                                 car/cdr.             (line   6)
* .car:                                  car/cdr.             (line   6)
* .case:                                 Traditional case.    (line   6)
* .cdar:                                 car/cdr.             (line   6)
* .cddr:                                 car/cdr.             (line   6)
* .cdr:                                  car/cdr.             (line   6)
* .cond:                                 Extended if/elseif/else.
                                                              (line   6)
* .div:                                  .div.                (line   6)
* .downcase:                             Convert a string to lowercase.
                                                              (line   6)
* .dump:                                 .dump.               (line   6)
* .eq:                                   .eq.                 (line   6)
* .equal?:                               .equal?.             (line   6)
* .error:                                .error.              (line   6)
* .eval:                                 Re-evaluating an expression.
                                                              (line   6)
* .exec:                                 Immediate execution of a command.
                                                              (line   6)
* .find:                                 Finding a subset of a list.
                                                              (line   6)
* .for-each:                             Iterating over a list.
                                                              (line   6)
* .ge:                                   .ge.                 (line   6)
* .gt:                                   .gt.                 (line   6)
* .hex:                                  Convert a number to a hex.
                                                              (line   6)
* .if:                                   Traditional if.      (line   6)
* .internal-test:                        Internal use pmacros.
                                                              (line  12)
* .inv:                                  .inv.                (line   6)
* .iota:                                 Number generation.   (line   6)
* .le:                                   .le.                 (line   6)
* .length:                               List length.         (line   6)
* .let:                                  Defining a block of locals.
                                                              (line   6)
* .let*:                                 Defining a block of locals.
                                                              (line   6)
* .list:                                 Creating lists.      (line   6)
* .lt:                                   .lt.                 (line   6)
* .map:                                  Mapping a macro over a list.
                                                              (line   6)
* .mul:                                  .mul.                (line   6)
* .ne:                                   .ne.                 (line   6)
* .not:                                  .not.                (line   6)
* .or:                                   .or.                 (line   6)
* .orif:                                 .orif.               (line   6)
* .pmacro:                               Defining a pmacro inline.
                                                              (line   6)
* .pmacro?:                              Testing if something is a pmacro.
                                                              (line   6)
* .print:                                .print.              (line   6)
* .ref:                                  Referencing a list element.
                                                              (line   6)
* .rem:                                  .rem.                (line   6)
* .replicate:                            Lists of repeated elements.
                                                              (line   6)
* .sll:                                  .sll.                (line   6)
* .splice:                               List splicing.       (line   6)
* .sra:                                  .sra.                (line   6)
* .srl:                                  .srl.                (line   6)
* .str:                                  String concatenation.
                                                              (line   6)
* .sub:                                  .sub.                (line   6)
* .substring:                            Getting part of a string.
                                                              (line   6)
* .sym:                                  Symbol concatenation.
                                                              (line   6)
* .upcase:                               Convert a string to uppercase.
                                                              (line   6)
* .xor:                                  .xor.                (line   6)
* anyof operands:                        Derived operands.    (line  35)
* Architecture variants:                 Architecture variants.
                                                              (line   6)
* Attributes:                            Attributes.          (line   6)
* Attributes, bitset:                    Attributes.          (line 112)
* Attributes, boolean:                   Attributes.          (line  43)
* Attributes, enumerated:                Attributes.          (line  91)
* Attributes, integer:                   Attributes.          (line  73)
* begin:                                 Multiple result statements.
                                                              (line   6)
* bfd-name:                              define-mach.         (line  24)
* decode-assist:                         define-isa.          (line  70)
* define-arch:                           define-arch.         (line   6)
* define-cpu:                            define-cpu.          (line   6)
* define-isa:                            define-isa.          (line   6)
* define-mach:                           define-mach.         (line   6)
* define-pmacro:                         Defining pmacros.    (line   6)
* Definitions:                           Definitions.         (line   6)
* Derived operands:                      Derived operands.    (line   6)
* Enumerated constants:                  Enumerated constants.
                                                              (line   6)
* Enumerations:                          Enumerated constants.
                                                              (line   6)
* Expressions:                           Expressions.         (line   6)
* insn-lsb0?:                            define-arch.         (line  30)
* Instruction fields:                    Instruction fields.  (line   6)
* Instruction fields, non-contiguous:    Instruction fields.  (line 172)
* Instruction operands:                  Instruction operands.
                                                              (line   6)
* Instructions:                          Instructions.        (line   6)
* Instructions, macro:                   Macro-instructions.  (line   6)
* Keywords:                              Keywords.            (line   6)
* liw-insns:                             define-isa.          (line  93)
* Macro-expressions:                     Macro-expressions.   (line   6)
* Macro-instructions:                    Macro-instructions.  (line   6)
* Miscellaneous notes:                   Miscellaneous notes. (line   6)
* Modes:                                 Modes.               (line   6)
* Number generation:                     Number generation.   (line   6)
* Opcodes support:                       Opcodes.             (line   6)
* Operands, anyof:                       Derived operands.    (line  35)
* Operands, derived:                     Derived operands.    (line   6)
* Operands, instruction <1>:             Derived operands.    (line   6)
* Operands, instruction:                 Instruction operands.
                                                              (line   6)
* parallel-insns:                        define-isa.          (line 100)
* pmacros:                               Preprocessor macros. (line   6)
* Porting:                               Porting.             (line   6)
* Preprocessor macros:                   Preprocessor macros. (line   6)
* Register Transfer Language:            RTL.                 (line   6)
* RTL:                                   RTL.                 (line   6)
* Semantics:                             Instructions.        (line 143)
* simplify.inc:                          simplify.inc.        (line   6)
* Simulation support:                    Simulation.          (line   6)
* Timing:                                Instructions.        (line 158)
* Top level conditionals:                Top level conditionals.
                                                              (line   6)
* version:                               Top.                 (line   6)
* Writing an application:                Writing an application.
                                                              (line   6)


