Helsinki

University

of

Technology

Department

of

Computer

Science

Digital

Systems

Laboratory

Otaniemi

Otakaari

FIN

ESPOO

FINLAND

HELSINKI

UNIVERSITY

OF

TECHNOLOGY

DIGITAL

SYSTEMS

LABORATORY

Series

B

Technical

Reports

ISSN

No.

March

ISBN

ReFlEx?AN

EXPERIMENTAL

TOOL

FOR

SPECIAL-PURPOSE

PROCESSOR

CODE

GENERATION

Eero

Lassila

Digital

Systems

Laboratory

Department

of

Computer

Science

Helsinki

University

of

Technology

Otaniemi

FINLAND

HELSINKI

UNIVERSITY

OF

TECHNOLOGY

DIGITAL

SYSTEMS

LABORATORY

Series

B

Technical

Reports

ISSN

No.

March

ISBN

ReFlEx?An

Experimental

Tool

for

Special-Purpose

Processor

Code

Generation

Eero

Lassila

Abstract

Code

generation

for

embedded

special-purpose

processors

is

usually

a

diOEcult

task

for

compiler

writers

as

well

as

for

assembly

language

programmers

This

report

describes

an

experimental

demonstration

prototype

of

a

code

generation

tool

The

tool

is

a

retargetable

assembly-code-level

macro

expander

capable

of

program

AEow

analysis

The

main

advantage

ooeered

by

this

macro

expander

is

its

strong

support

for

macro

hierarchy

The

enhanced

modularity

provided

by

hierarchical

macro

libraries

can

make

the

code

-LRB-

produced

either

by

the

compiler

writer

or

by

the

assembly

language

programmer

-RRB-

more

easily

readable

maintainable

and

reusable

Still

a

procedure

written

in

the

macro

language

retains

its

machine-speciocity

and

consequently

its

eOEciency

Printing

TKK

Monistamo

Otaniemi

Helsinki

University

of

Technology

Phone

Department

of

Computer

Science

Digital

Systems

Laboratory

Telex

htkk

o

Otaniemi

Otakaari

Telefax

FIN

ESPOO

FINLAND

E-mail

lab@saturn.hut.o

i

Contents

Introduction

Background

Notion

of

AEow-sensitivity

Overview

of

the

proposed

tool

Implications

on

target

hardware

Outline

of

this

report

Tutorial

Overall

rule

base

structure

Expansion-time

expression

interpreter

Available

data

storage

Machine

instruction

set

Higher-level

macros

Generating

code

for

macro

calls

Target

architecture

model

Code

storage

Data

storage

Comparison

with

real

machine

instruction

sets

Our

machine

instruction

model

On

syntactical

conventions

Characters

Tokens

Structuring

mechanisms

ii

Constant

expressions

Taxonomy

of

integer

cell

and

label

designators

Integer

literals

Form

calls

Integer

cell

and

label

references

Autonomous

primitive

forms

Context-sensitive

primitive

forms

Rigid

compound

forms

Flexible

compound

forms

Macro

deonitions

General

structure

of

a

macro

deonition

System

macros

Control

transfer

Macro

parameters

and

arguments

Structure

of

a

version

deonition

Test

assertion

and

insist

clauses

Macro

temporaries

Initialization

of

data

variables

Safety

declarations

Form

calls

in

macro

deonitions

Macro

expansion

procedure

Overall

linking

strategy

Preliminary

deonitions

Free

cell

analysis

Variable

binding

Accepting

or

rejecting

a

macro

version

iii

Safeguarding

Merging

phase

Input

and

output

Expansion

source

Expansion

result

Intermediate

tree

structure

Running

ReFlEx

Invoking

ReFlEx

Command-line

options

Interactive

control

Exceptional

conditions

and

exception

messages

Installing

ReFlEx

Technical

information

about

ReFlEx

Obtaining

a

copy

of

ReFlEx

A

Rule

ole

syntax

B

Expansion

source

syntax

C

A

sample

code

generator

Acknowledgements

References

Introduction

In

this

report

we

propose

a

novel

method

for

machine

code

generation

Basically

the

tool

we

have

implemented

is

a

retargetable

assembly-code-level

macro

expander

it

transforms

a

higher-level

but

still

machine-specioc

program

description

into

assembly

language

Governed

by

user-written

rules

-LRB-

i.e.

macro

deonitions

-RRB-

the

expander

can

generate

code

for

dioeerent

target

processors

The

prototype

design

documented

here

ReFlEx

is

intended

for

demonstrative

purposes

only

it

is

not

yet

meant

for

coping

with

real

processor

architectures

However

we

believe

that

a

similar

but

considerably

more

advanced

tool

might

meet

many

of

the

challenges

posed

by

modern

embedded

special-purpose

processor

architectures

Currently

embedded

processor

code

generation

-LSB-

-RSB-

is

a

most

demanding

task

for

high-level

language

compiler

writers

as

well

as

for

assembly

language

programmers

Our

ultimate

goal

is

to

support

both

of

these

two

groups

of

software

professionals

in

their

work

The

name

ReFlEx

of

the

implemented

program

comes

from

a

Retargetable

Flow-sensitive

macro

Expander

The

idea

of

making

a

macro

expander

perform

full

program

AEow

analysis

is

the

essence

of

our

work

-LRB-

To

avoid

confusion

we

speak

of

macro

expanders

instead

of

the

more

common

macro

processors

by

a

processor

we

always

refer

to

computer

hardware

-RRB-

Background

In

computer

programs

abstraction

through

modularity

improves

readability

maintainability

and

reusability

the

details

of

a

module

implementation

become

hidden

from

the

clients

of

the

module

Object-oriented

programming

is

one

of

the

popular

modularity-promoting

mechanisms

at

the

highlevel

language

level

we

try

to

convince

you

that

the

use

of

relatively

powerful

modularity-promoting

mechanisms

may

be

justioed

even

at

the

assembly

language

level

Do

we

really

need

to

bother

much

about

the

peculiarities

of

assembly

languages

Is

it

not

so

that

RISC-type

microprocessors

are

speciocally

designed

to

be

programmed

with

optimizing

high-level

language

compilers

The

answer

to

the

latter

question

is

yes

-LSB-

-RSB-

of

course

but

there

are

also

many

important

special-purpose

processors

for

which

no

compiler

available

seems

to

be

good

enough

Typically

such

processors

are

used

in

embedded

real-time

computing

systems

representative

examples

can

be

found

among

digital

signal

processors

-LRB-

DSPs

-RRB-

-LSB-

-RSB-

In

many

telecommunication

systems

for

instance

compiled

code

is

currently

ruled

out

by

eOEciency

requirements

Thus

the

programmers

get

themselves

involved

in

the

mess

known

as

assembly

language

programming

Special-purpose

processor

architectures

present

programmers

with

three

inherent

technical

complications?all

of

which

are

closely

related

to

the

eOE

ciency

requirement

ffl

Unconventional

functionality

with

both

limitations

and

extensions

ffl

Architectural

irregularity

a

heterogeneous

register

set

and

an

idiosyncratic

instruction

set

ffl

Fine

instruction

granularity

Unconventional

functionality

and

architectural

irregularity

are

burdens

to

the

compiler

writer

They

stem

from

the

utmost

adaptation

to

the

narrow

oeld

of

intended

applications

the

general-purpose

RISC

chips

in

contrast

have

regular

architectures

Because

of

the

irregularity

the

case

analysis

needed

in

code

generation

soon

becomes

too

enormous

for

compiler

writers

as

noticed

by

Wulf

in

-LSB-

-RSB-

Fine

instruction

granularity

on

the

other

hand

is

the

feature

that

makes

the

work

of

the

assembly

language

programmer

laborious

and

error-prone

because

individual

instructions

are

relatively

primitive

more

code

lines

have

to

be

written

A

representative

example

of

one

granularity

is

that

in

some

processor

architectures

loads

and

stores

are

the

only

possible

forms

of

memory

access

-LRB-

for

instance

prior

to

launching

an

addition

instruction

both

the

addends

must

be

explicitly

fetched

from

memory

-RRB-

Fine

instruction

granularity

-LRB-

with

hardwired

control

-RRB-

seems

to

correlate

with

high

execution

speed

RISC

instructions

are

also

one-grained

Notion

of

AEow-sensitivity

Macro

expansion

-LSB-

-RSB-

is

a

simple

modularity-promoting

mechanism

traditionally

used

at

the

assembly

language

level

-LSB-

-RSB-

However

conventional

assembly

language

macros

can

not

be

freely

used

hierarchically

For

instance

if

some

macro

internally

uses

a

certain

register

R

as

a

temporary

data

storage

the

programmer

has

to

take

care

when

calling

the

macro

expander

is

not

able

to

issue

a

warning

that

the

value

possibly

already

stored

in

R

will

be

lost

during

the

execution

of

-LSB-

pp.

-RSB-

Additionally

if

in

turn

calls

another

macro

say

then

the

original

caller

of

must

take

into

consideration

even

similar

restrictions

that

perhaps

concern

In

general

such

implicit

restrictions

eoeectively

prevent

the

introduction

of

macro

hierarchy

To

support

unrestricted

macro

hierarchy

the

macro

expander

must

not

be

a

simple

text

string

substitution

engine

but

a

more

sophisticated

tool

aware

of

the

control

and

data

AEow

of

the

underlying

program

Optimizing

compilers

-LSB-

-RSB-

perform

program

AEow

analysis

-LSB-

-RSB-

we

apply

it

even

to

macro

expansion

The

usefulness

of

AEow-sensitivity

becomes

apparent

with

the

following

C

code

fragment

while

-LRB-

x

-RRB-

-LCB-

C

code

y

x

y

w

liboper

-LRB-

z

-RRB-

x

z

w

-RCB-

Let

us

assume

that

the

C

compiler

we

use

can

hold

all

the

variables

x

y

z

and

w

in

registers

Furthermore

we

assume

that

the

compiler

recognizes

the

liboper

library

function

and

is

able

to

treat

it

as

a

macro

that

is

to

replace

its

call

with

inline

assembly

code

-LSB-

Ch

-RSB-

Finally

we

suppose

that

the

compiler

contains

a

non-trivial

precompiler

that

allocates

the

registers

reserved

for

the

register

variables

and

expands

such

library

macros

as

liboper

Now

AEow-sensitivity

would

allow

the

precompiler

to

observe

that

when

this

liboper

macro

call

is

expanded

the

register

allocated

for

x

is

free

to

be

used

as

a

temporary

storage

but

the

one

allocated

for

y

is

not

-LRB-

x

is

rewritten

by

the

last

statement

of

the

loop

body

but

y

has

to

retain

its

value

throughout

the

last

two

loop

body

statements

-RRB-

Accordingly

the

essential

advantage

of

AEow-sensitivity

is

that

the

expander

knows

which

registers

are

free

at

the

point

of

each

macro

call

A

register

is

free

if

it

is

guaranteed

not

to

contain

data

that

should

not

be

overwritten

i.e.

data

earlier

written

into

it

and

later

to

be

read

from

it

Then

the

suggested

division

of

labor

is

as

follows

the

human

programmer

-LRB-

e.g.

a

compiler

writer

-RRB-

only

chooses

the

optimum

register

class

for

each

macro

temporary

the

macro

expander

then

tries

to

ond

a

free

member

of

the

chosen

class

Thus

the

programmer

is

released

from

a

great

deal

of

tedious

bookkeeping

If

a

macro

expander

could

reach

adequate

AEow-sensitivity

we

could

at

least

in

principle

construct

hierarchical

libraries

with

conditional

macro

deonitions

as

building

blocks

Such

libraries

would

in

turn

make

the

assembly

code

more

easily

readable

maintainable

and

reusable

Indeed

in

later

sections

of

this

report

we

are

able

to

present

concrete

examples

of

multilevel

macro

hierarchy

Our

most

severe

problem

lies

in

monitoring

all

the

versatile

equipment

that

processors

use

to

implement

the

control

and

data

AEow

In

this

report

we

have

had

to

adopt

strong

constraints

on

this

equipment

Most

importantly

we

have

excluded

the

possibility

of

indirect

addressing

Note

however

that

often

only

memory

locations

and

not

CPU

registers

can

be

addressed

indirectly

-LRB-

In

the

future

we

aim

at

programmer-assisted

mechanisms

for

alias

analysis

-LSB-

Sec.

-RSB-

-RRB-

Overview

of

the

proposed

tool

We

propose

the

AEow-sensitive

macro

expander

as

a

tool

for

both

assembly

language

programmers

and

compiler

writers?in

other

words

both

as

a

standalone

macro

assembler

and

as

the

onal

part

of

a

compiler

back-end

Flow-sensitive

macro

expansion

as

well

as

macro

expansion

in

general

requires

two

main

components

the

macro

expander

proper

and

a

rule

base

consisting

of

macro

deonitions

Because

the

tool

must

be

taught

the

target

instruction

set

we

deem

it

appropriate

to

divide

the

rule

base

explicitly

into

system

macros

and

application

macros

as

shown

in

Figure

The

machine

instructions

of

the

target

processor

are

visible

to

the

application

macro

programmer

only

through

the

system

macros

which

constitute

the

basis

of

the

macro

hierarchy?they

are

actually

not

genuine

macros

but

mere

placeholders

for

individual

machine

instructions

Application

macro

deonitions

can

be

hierarchical

in

the

deonition

of

an

application

macro

A

you

may

call

any

macro

B

The

task

of

the

macro

expander

is

to

convert

each

application

macro

call

in

the

input

program

into

a

sequence

of

system

macro

calls

processor-specioc

system

library

processor-independent

macro

expander

APPLICATION

MACROS

SYSTEM

MACROS

processor-specioc

programming

tool

processorspecioc

expansion

source

processorspecioc

expansion

result

APPLICATION

MACRO

CALLS

SYSTEM

MACRO

CALLS

processor-specioc

utility

library

ff

Figure

Operation

of

the

proposed

programming

tool

Although

the

macro

expander

proper

is

intended

to

be

easily

retargetable

we

do

not

expect

that

application

programs

would

be

portable

across

dioeerent

target

hardware

As

implicitly

expressed

above

the

purpose

of

the

system

macro

set

is

not

to

create

a

standard

machine-independent

programmer-visible

layer

by

hiding

the

machine-specioc

details

On

the

contrary

the

system

macros

exploit

these

very

details

in

a

controlled

but

still

transparent

fashion

There

should

be

a

natural

one-to-one

mapping

between

the

system

macros

and

the

target

machine

instructions

For

accuracy

the

system

macro

set

should

be

specioed?and

perhaps

even

the

core

of

the

application

macro

library

should

be

written?by

a

single

system

manager

-LRB-

and

not

by

application

macro

programmers

-RRB-

Macros

of

any

kind

typically

do

not

have

any

predeoned

semantics

contrary

to

the

built-in

elements

of

programming

languages

The

power

of

the

proposed

approach

is

in

the

generality

resulting

from

this

lack

For

a

simplioed

example

suppose

that

the

target

processor

instruction

set

contains

an

ADD

instruction

that

reads

two

registers

and

writes

one

register

Suppose

also

that

the

programmer

uses

the

ADD

instruction

-LRB-

i.e.

the

corresponding

system

macro

-RRB-

inside

the

deonition

of

some

application

macro

MAC

When

the

macro

expander

then

tries

to

expand

some

call

of

MAC

all

that

it

has

to

do

concerning

the

ADD

instance

is

to

select

three

appropriate

registers

-LRB-

in

particular

it

must

take

care

that

the

data

possibly

already

present

in

the

output

register

is

not

prematurely

overwritten

-RRB-

Thus

it

can

ignore

a

great

deal

of

information

relevant

to

any

high-level

language

compiler

Most

importantly

it

need

not

even

know

whether

ADD

actually

performs

an

addition

or

something

wholly

dioeerent

To

sum

up

the

lack

of

predeoned

semantics

ooeers

the

following

advantages

ffl

The

macro

expander

proper

can

be

made

a

relatively

small

program

It

is

the

rule

base

consisting

of

macro

deonitions

that

drives

the

expansion

ffl

With

suitable

macro

deonitions

the

tool

can

be

tailored

to

fully

exploit

the

particulars

of

the

chosen

target

processor

architecture

ffl

Operations

not

needed

in

the

chosen

application

need

not

be

supported

Implications

on

target

hardware

The

AEow-sensitive

macro

expansion

is

aimed

at

tackling

the

case

analysis

problem

in

code

generation

Obviously

this

problem

is

most

severe

when

the

target

architecture

is

an

irregular

one?when

the

register

set

is

heterogeneous

and

the

instruction

set

is

idiosyncratic

Accordingly

among

the

presently

marketed

processors

we

spot

the

oxed-point

DSP

chips

as

our

most

promising

targets

-LRB-

admittedly

we

need

an

additional

postprocessor

program

for

code

compaction

-LSB-

-RSB-

-RRB-

In

particular

even

among

DSPs

we

focus

on

processors

with

narrowest

functionality

highest

speed

and

lowest

price

-LRB-

such

as

-LSB-

-RSB-

-RRB-

We

realize

that

the

AEow-sensitive

macro

expansion

approach

can

even

as

its

best

be

feasible

only

for

a

strongly

restricted

class

of

processor

architectures

-LRB-

see

-LSB-

-RSB-

for

some

challenging

ones

of

the

numerous

intricacies

typically

found

in

DSP

architectures

-RRB-

Therefore

this

class

must

be

given

a

detailed

characterization

We

believe

that

a

prospective

macro

expander

implementor

should

at

orst

be

content

with

an

unrealistically

narrow

characterization

and

only

after

a

successful

prototype

strive

for

step-by-step

extensions

A

signiocant

reason

for

not

attacking

directly

the

commercial

architectures

is

that

even

a

narrow

characterization

may

perhaps

serve

as

a

constraint

on

future

processor

design

in

a

somewhat

similar

fashion

the

RISC

processors

are

designed

speciocally

to

be

programmed

with

optimizing

high-level

language

compilers

Adopting

additional

architectural

constraints

of

the

suggested

kind

might

pay

especially

in

rapid

prototyping

-LSB-

-RSB-

of

embedded

computer

systems

Moreover

our

approach

promotes

customized

application-specioc

instruction

set

processors

-LSB-

-RSB-

as

possible

implementations

for

microelectronic

systems

with

a

tight

development

schedule

For

such

a

processor

the

proposed

macro

expander

could

provide

an

almost

ready-to-use

code

generation

tool

with

such

an

application

the

lack

of

portability

across

dioeerent

target

hardware

is

often

insigniocant

Outline

of

this

report

In

Section

we

present

a

tutorial

that

gives

you

a

orst

impression

of

the

implemented

AEow-sensitive

macro

expander

ReFlEx

The

overly

simple

target

processor

architectures

supported

by

ReFlEx

are

characterized

in

Section

Section

describes

general

notational

conventions

of

the

macro

deonition

language

Before

the

features

of

the

macro

deonition

language

are

dealt

with

in

detail

in

Section

Section

describes

an

essential

supplementary

facility

a

user-extensible

interpreter

for

evaluating

arithmetic

and

AEow-sensitive

expressions

at

expansion

time

Section

discusses

the

general

principles

of

the

internal

operation

of

ReFlEx

Section

gives

a

detailed

description

of

the

input

and

output

of

the

expander

the

expansion

source

and

result

Section

describes

how

the

expander

is

run

and

what

kind

of

problems

may

consequently

emerge

Finally

Section

contains

some

technical

information

In

particular

it

specioes

how

you

can

obtain

a

copy

of

an

up-to-date

revision

of

ReFlEx

and

installation

instructions

for

it

The

program

can

be

installed

and

used

for

any

non-commercial

purposes

without

charge

Appendices

A

and

B

serve

as

references

covering

the

syntax

of

the

macro

deonitions

and

the

expansion

source

respectively

Appendix

C

contains

a

sample

set

of

macro

deonitions

that

constitutes

a

simple

code

generator

-LRB-

This

last

appendix

also

includes

an

exercise

that

can

be

used

as

a

diagnostic

selftest

-RRB-

Tutorial

ReFlEx

reads

the

macro

deonitions

from

a

rule

ole

In

this

section

we

write

step

by

step?a

simple

rule

ole

Then

in

the

last

subsection

we

are

able

to

run

some

elementary

code

generation

examples

To

be

able

to

run

the

examples

yourself

you

should

have

the

ReFlEx

program

successfully

installed

see

Section

for

instructions

This

tutorial

ignores

some

of

the

more

advanced

features

of

the

macro

deonition

language

Moreover

concerning

even

the

basic

features

the

presentation

here

is

only

introductory

Having

read

this

section

you

have

most

likely

still

to

learn

more

to

be

able

to

write

your

own

rule

oles

A

complete

description

of

the

macro

deonition

language

is

given

in

Sections

and

Overall

rule

base

structure

The

rule

ole

should

be

a

plain

ASCII

ole

It

is

to

be

divided

into

four

logical

parts

-LRB-

each

of

which

typically

extends

over

several

lines

-RRB-

HEADER

-LCB-

-RCB-

STORAGE

-LCB-

-RCB-

SYSTEM

-LCB-

-RCB-

UTILITY

-LCB-

-RCB-

Figure

Overall

structure

of

the

rule

ole

The

HEADER

part

contains

auxiliary

deonitions

In

the

STORAGE

part

we

specify

the

available

run-time

data

storage

i.e.

the

CPU

registers

and

the

data

memory

The

system

and

application

macros

are

described

in

the

SYSTEM

and

UTILITY

parts

respectively

Below

Section

which

deals

with

the

HEADER

part

may

well

be

read

only

cursorily

It

is

included

only

because

it

contains

some

deonitions

without

which

our

rule

ole

would

be

technically

incomplete

even

if

still

an

intuitive

one

Expansion-time

expression

interpreter

In

the

HEADER

part

of

the

rule

ole

we

may

deone

new

expressions

for

the

builtin

expansion-time

expression

interpreter

For

instance

here

is

the

obvious

recursive

deonition

for

the

factorial

function

Fact

-LRB-

a

-RRB-

If

-LRB-

Lt

-LRB-

a

-RRB-

Mul

-LRB-

a

Fact

-LRB-

Add

-LRB-

-RRB-

-RRB-

-RRB-

-RRB-

The

expressions

recognized

by

the

interpreter

are

called

forms

The

forms

If

Lt

Mul

and

Add

are

primitive

that

is

predeoned

-LRB-

As

a

rule

if

a

primitive

form

has

an

alphanumeric

name

then

that

name

begins

with

an

underscore

-RRB-

Not

surprisingly

Lt

Mul

and

Add

are

less-than

multiplication

and

addition

respectively

As

for

If

if

its

orst

argument

is

nonzero

it

returns

the

value

of

the

second

argument

otherwise

it

returns

the

value

of

the

third

argument

This

special

primitive

form

supports

lazy

evaluation

because

only

the

needed

arguments

are

evaluated

The

forms

deoned

by

the

user

are

called

compound

ones

A

compound

form

is

either

rigid

or

AEexible

A

rigid

form

always

expects

a

oxed

number

of

arguments

whereas

a

AEexible

form

may

take

any

number

of

arguments

Like

all

the

forms

dealt

with

in

this

section

Fact

is

rigid

Then

Figure

introduces

some

more

compound

forms

Not

Is

the

argument

zero

Gte

Is

the

orst

argument

greater

than

or

equal

to

the

second

one

Are

the

two

arguments

both

nonzero

Is

at

least

one

of

the

two

arguments

nonzero

Eq

Are

the

two

arguments

equal

Int

Is

the

argument

an

integer

Zero

Is

the

argument

an

integer

equal

to

zero

Not

-LRB-

a

-RRB-

Nand

-LRB-

a

a

-RRB-

Gte

-LRB-

a

b

-RRB-

Not

-LRB-

Lt

-LRB-

a

b

-RRB-

-RRB-

-LRB-

a

b

-RRB-

If

-LRB-

a

If

-LRB-

b

-RRB-

-RRB-

-LRB-

a

b

-RRB-

If

-LRB-

a

If

-LRB-

b

-RRB-

-RRB-

Eq

-LRB-

a

b

-RRB-

-LRB-

Not

-LRB-

Lt

-LRB-

a

b

-RRB-

-RRB-

Not

-LRB-

Lt

-LRB-

b

a

-RRB-

-RRB-

-RRB-

Int

-LRB-

a

-RRB-

-LRB-

Not

-LRB-

-LRB-

a

-RRB-

-RRB-

Not

-LRB-

-LRB-

a

-RRB-

-RRB-

-RRB-

Zero

-LRB-

a

-RRB-

-LRB-

Int

-LRB-

a

-RRB-

Eq

-LRB-

a

-RRB-

-RRB-

Figure

Deonitions

of

rigid

compound

forms

There

is

an

essential

dioeerence

between

the

two

forms

Not

and

Zero

if

the

argument

turns

out

not

to

represent

an

integer

Not

always

returns

a

nonzero

value

but

Zero

returns

zero

The

explanation

is

that

the

virtual

form

arguments

-LRB-

which

are

employed

in

the

rule

ole

-RRB-

may

in

addition

to

integers

designate

storage

cells

or

instruction

labels

which

are

always

interpreted

as

zeros

if

they

appear

where

an

integer

is

expected

The

and

primitive

forms

used

in

the

Int

deonition

check

whether

their

arguments

are

storage

cells

or

instruction

labels

respectively

Available

data

storage

Our

imaginary

target

processor

architecture

is

utterly

simplioed

As

shown

in

Figure

there

are

memory

locations

M

-LSB-

-RSB-

M

-LSB-

-RSB-

four

auxiliary

registers

R

-LSB-

-RSB-

R

-LSB-

-RSB-

and

a

single

accumulator

A

-LRB-

due

to

the

singularity

A

can

be

used

as

a

shorthand

for

A

-LSB-

-RSB-

-RRB-

Thus

there

are

three

distinct

storage

classes

whose

members

are

collectively

called

storage

cells

or

simply

cells

ReFlEx

assumes

that

the

members

of

each

single

storage

class

can

be

used

fully

interchangeably

STORAGE

-LCB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

A

-LSB-

-RSB-

-RCB-

Figure

Declaration

of

data

storage

cells

Note

that

ReFlEx

itself

need

not

to

know

the

cell

lengths

-LRB-

which

may

well

be

dioeerent

for

dioeerent

classes

-RRB-

in

terms

of

bit

positions

On

the

other

hand

any

professional

ReFlEx

user

should

absolutely

be

familiar

with

this

information

-LRB-

In

accordance

with

the

established

compiler

terminology

we

say

that

Figure

contains

a

declaration

In

general

a

declaration

introduces

the

name

of

an

entity

without

specifying

the

internal

structure

of

the

entity

-RRB-

Machine

instruction

set

Next

in

Figure

we

declare

the

system

macros

which

represent

the

machine

instructions

of

the

target

What

we

deone

is

actually

only

the

interface

seen

by

application

macro

programmers

ReFlEx

can

not

convert

system

macro

calls

into

real

machine

instructions

what

it

is

able

to

do

is

to

convert

application

macro

calls

into

system

macro

call

sequences

We

claim

that

this

latter

task

is

the

interesting

one

while

the

former

task

should

be

a

routine

matter

and

therefore

relegated

to

a

ReFlEx-compatible

assembler

So

there

are

in

all

ten

system

macros

among

which

there

are

one

unconditional

branch

-LRB-

JUMP

-RRB-

and

three

conditional

branches

-LRB-

BRANCH

-RRB-

Most

of

the

system

macros

are

provided

with

a

test

-LRB-

TEST

-RRB-

that

constrains

their

use

ReFlEx

does

not

know

their

full

semantics

which

must

of

course

be

known

SYSTEM

-LCB-

set

-LRB-

c

r

-RRB-

-LCB-

TEST

-LRB-

-LRB-

R

-LRB-

r

-RRB-

Int

-LRB-

c

-RRB-

-RRB-

-LRB-

Gte

-LRB-

-RRB-

Lt

-LRB-

c

-RRB-

-RRB-

-RRB-

-RCB-

load

-LRB-

m

r

-RRB-

-LCB-

TEST

-LRB-

R

-LRB-

r

-RRB-

M

-LRB-

m

-RRB-

-RRB-

-RCB-

store

-LRB-

r

m

-RRB-

-LCB-

TEST

-LRB-

R

-LRB-

r

-RRB-

M

-LRB-

m

-RRB-

-RRB-

-RCB-

move

-LRB-

s

d

-RRB-

-LCB-

TEST

-LRB-

-LRB-

A

-LRB-

s

-RRB-

R

-LRB-

s

-RRB-

-RRB-

-LRB-

A

-LRB-

d

-RRB-

R

-LRB-

d

-RRB-

-RRB-

-RRB-

-RCB-

add

-LRB-

a

r

a

-RRB-

-LCB-

TEST

-LRB-

A

-LRB-

a

-RRB-

R

-LRB-

r

-RRB-

-RRB-

-RCB-

sub

-LRB-

a

r

a

-RRB-

-LCB-

TEST

-LRB-

A

-LRB-

a

-RRB-

R

-LRB-

r

-RRB-

-RRB-

-RCB-

JUMP

goto

-LRB-

-RRB-

-LSB-

l

-RSB-

-LCB-

-RCB-

BRANCH

eq

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-LCB-

TEST

A

-LRB-

a

-RRB-

-RCB-

BRANCH

gt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-LCB-

TEST

A

-LRB-

a

-RRB-

-RCB-

BRANCH

lt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-LCB-

TEST

A

-LRB-

a

-RRB-

-RCB-

-RCB-

Figure

Declaration

of

system

macros

to

the

application

macro

programmer

With

the

information

seen

in

Figure

even

the

following

brief

description

should

be

fairly

comprehensive

for

a

prospective

application

macro

programmer

ffl

set

reads

a

signed

integer

and

writes

it

into

one

of

the

auxiliary

registers

-LRB-

form

R

checks

whether

its

arguments

belong

to

storage

class

R

-RRB-

Thus

set

is

for

immediate

addressing

for

the

value

of

the

integer

is

oxed

at

expansion

time

ffl

load

copies

the

contents

of

a

memory

location

into

an

auxiliary

register

and

store

performs

the

opposite

data

transfer

ffl

move

can

move

data

between

two

storage

cells

provided

that

each

one

of

the

cells

is

either

the

accumulator

or

an

auxiliary

register

ffl

add

adds

the

contents

of

one

of

the

auxiliary

registers

into

the

accumulator

Thus

it

reads

and

writes

the

accumulator

and

additionally

reads

an

auxiliary

register

Similarly

sub

performs

a

corresponding

subtraction

ffl

goto

jumps

to

the

specioed

instruction

label

ffl

eq

gt

and

lt

branch

to

the

specioed

label

if

the

contents

of

the

accumulator

are

respectively

equal

to

zero

positive

or

negative

Thus

they

all

read

the

accumulator

From

this

rather

restricted

system

macro

set

we

may

infer

that

the

actual

target

processor

instruction

set

is

similarly

restricted

Note

in

particular

that

the

accumulator

can

not

be

loaded

directly

from

memory

Higher-level

macros

Now

we

are

ready

to

deone

application

macros

without

which

the

rule

ole

would

not

be

of

any

use

Our

orst

application

macro

shown

in

Figure

is

most

simple

it

does

not

do

anything

Still

it

is

a

useful

macro

as

you

will

see

later

-LRB-

Actually

the

essential

feature

of

is

the

requirement

that

the

input

and

output

arguments

must

be

the

same

cell

-RRB-

-LRB-

x

x

-RRB-

-LCB-

-LCB-

-RCB-

-RCB-

Figure

Deonition

of

the

application

macro

The

macro

in

Figure

then

implements

a

general

data

transfer

not

subject

to

any

storage

class

restrictions

contrary

to

the

system

macros

declared

above

The

macro

deonition

consists

of

seven

alternative

versions

each

with

a

distinct

name

The

versions

are

listed

in

the

order

of

decreasing

priority

i.e.

in

the

order

in

which

ReFlEx

should

try

to

apply

them

to

each

call

Note

that

the

version

for

instance

can

be

accepted

only

if

the

source

of

the

data

transfer

is

an

signed

integer

and

the

destination

is

an

auxiliary

register

because

the

test

associated

with

the

set

macro

in

Figure

rejects

calls

of

other

kinds

In

Figure

in

contrast

all

the

tests

are

associated

with

some

version

of

the

macro

not

directly

with

the

macro

itself

Let

us

look

closely

at

each

one

of

the

versions

ffl

same

guarantees

that

the

expansion

result

is

an

empty

code

sequence

when

the

source

and

the

destination

are

the

same

cell

The

empty

call

serves

two

purposes

it

verioes

that

parameters

s

and

d

do

represent

the

same

cell

and

it

writes

the

output

parameter

d

-LRB-

see

Section

for

the

constraint

concerned

here

-RRB-

ffl

and

may

only

be

converted

into

the

respective

corresponding

system

macros

-LRB-

s

d

-RRB-

-LCB-

same

-LCB-

-LRB-

s

d

-RRB-

-RCB-

-LCB-

set

-LRB-

s

d

-RRB-

-RCB-

INSIST

Not

-LRB-

-LRB-

Int

-LRB-

s

-RRB-

R

-LRB-

d

-RRB-

-RRB-

-RRB-

-LCB-

load

-LRB-

s

d

-RRB-

-RCB-

-LCB-

store

-LRB-

s

d

-RRB-

-RCB-

-LCB-

move

-LRB-

s

d

-RRB-

-RCB-

TEST

Zero

-LRB-

s

-RRB-

USE

R

-LSB-

r

-RSB-

-LCB-

INIT

-LRB-

r

-RRB-

move

-LRB-

r

d

-RRB-

sub

-LRB-

d

r

d

-RRB-

-RCB-

USE

R

-LSB-

r

-RSB-

-LCB-

-LRB-

s

r

-RRB-

-LRB-

r

d

-RRB-

-RCB-

-RCB-

Figure

Deonition

of

the

application

macro

ffl

is

used

for

resetting

the

accumulator

without

having

to

overwrite

any

auxiliary

register

the

auxiliary

register

represented

by

the

temporary

r

is

only

read

and

not

written

The

INIT

pseudomacro

is

speciocally

aimed

at

situations

of

this

kind

-LRB-

INIT

is

the

only

pseudomacro

of

the

language

-RRB-

ffl

requires

a

free

auxiliary

register

This

register

is

used

as

an

intermediate

storage

when

for

instance

the

contents

of

a

memory

location

are

to

be

transferred

into

the

accumulator

The

version

is

recursive

but

the

recursion

depth

can

be

seen

to

be

at

most

one

In

Figure

the

INSIST

clause

detects

such

integers

that

were

too

large

for

the

set

system

macro

Removal

of

this

clause

would

allow

non-terminating

recursion

instead

of

the

controlled

failure

naturally

preferred

by

the

macro

writer

Like

our

next

example

is

also

a

storage-class-independent

generalization

The

macro

which

is

shown

in

Figure

is

a

branch

that

is

taken

if

the

value

represented

by

its

argument

is

equal

to

zero

-LRB-

The

expansion

result

of

a

sample

call

will

be

shown

in

Figure

in

Section

-RRB-

Note

that

the

empty

next

version

of

which

employs

reserved

word

NEXT

matches

the

case

in

which

the

branch

target

i.e.

the

instruction

labeled

by

l

immediately

follows

the

call

Our

fourth

and

onal

application

macro

shown

in

Figure

interchanges

the

contents

of

two

memory

locations

This

is

our

orst

application

BRANCH

-LRB-

x

-RRB-

-LSB-

l

-RSB-

-LCB-

next

TEST

-LRB-

l

NEXT

-RRB-

-LCB-

-RCB-

TEST

Zero

-LRB-

x

-RRB-

-LCB-

JUMP

goto

-LRB-

-RRB-

-LSB-

l

-RSB-

-RCB-

const

TEST

Int

-LRB-

x

-RRB-

-LCB-

-RCB-

acc

TEST

A

-LRB-

x

-RRB-

-LCB-

BRANCH

eq

-LRB-

x

-RRB-

-LSB-

l

-RSB-

-RCB-

default

USE

A

-LSB-

a

-RSB-

-LCB-

-LRB-

x

a

-RRB-

BRANCH

eq

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-RCB-

Figure

Deonition

of

the

application

macro

macro

with

which

a

test

-LRB-

i.e.

one

that

verioes

the

storage

class

-RRB-

is

directly

associated

-LRB-

Section

will

also

present

the

expansion

result

of

a

sample

call

in

Figure

-RRB-

-LRB-

m

n

n

m

-RRB-

-LCB-

TEST

M

-LRB-

m

n

-RRB-

TEST

Gte

-LRB-

R

-LRB-

-RRB-

-RRB-

USE

R

-LSB-

r

-RSB-

-LCB-

-LRB-

m

r

-RRB-

-LRB-

n

m

-RRB-

-LRB-

r

n

-RRB-

-RCB-

USE

A

-LSB-

a

-RSB-

-LCB-

-LRB-

m

a

-RRB-

-LRB-

n

m

-RRB-

-LRB-

a

n

-RRB-

-RCB-

-RCB-

Figure

Deonition

of

the

application

macro

To

perform

the

swap

requires

two

cells

of

free

storage

because

direct

transfers

between

memory

locations

are

not

supported

by

the

system

macro

set

At

least

one

of

these

two

cells

must

be

an

auxiliary

register

while

the

other

one

may

alternatively

be

the

accumulator

Accordingly

form

R

seen

in

the

deonition

returns

the

number

of

free

cells

in

storage

class

R.

-LRB-

The

test

associated

with

the

version

is

necessary

because

in

the

version

code

only

one

auxiliary

register

i.e.

r

is

written

but

the

middle

one

of

the

lower-level

calls

certainly

needs

another

one

Without

the

test

might

be

selected

even

in

such

a

case

that

the

version

might

be

the

only

fully

expandable

one

of

these

two

This

is

because

ReFlEx

can

not

backtrack

from

choices

that

only

at

some

later

stage

prove

to

be

unsuccessful

-RRB-

Generating

code

for

macro

calls

Finally

in

this

last

subsection

of

Section

we

put

our

macro

deonitions

into

use

and

produce

some

code

for

our

target

processor

We

must

start

with

a

single

macro

call

ReFlEx

expects

that

the

expansion

source

can

be

represented

as

one

top-level

macro

call

Suppose

that

ReFlEx

has

been

installed

on

our

workstation

and

our

rule

ole

is

called

simple.m

We

can

start

ReFlEx

by

typing

the

following

command

-LRB-

the

combination

of

options

t

and

f

provides

us

with

some

interesting

optional

output

-RRB-

reflex

t

f

simple.m

If

ReFlEx

starts

successfully

we

may

then

type

the

following

expansion

source

as

a

response

to

the

ReFlEx

prompt

i.e.

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

This

means

that

we

want

to

branch

to

label

if

the

contents

of

memory

location

M

-LSB-

-RSB-

are

zero

and

we

additionally

specify

that

accumulator

A

and

auxiliary

register

R

-LSB-

-RSB-

are

free

at

the

macro

call

-LRB-

an

explicit

speciocation

like

this

is

needed

and

allowed

only

in

the

expansion

source

-RRB-

The

expansion

result

is

shown

in

Figure

The

intermediate

output

at

the

top

reveals

the

expansion-time

tree

structure

which

is

AEattened

in

the

onal

output

at

the

bottom

Each

macro

call

is

provided

with

a

set

containing

the

cells

that

are

free

at

it

-LRB-

normally

each

cell

written

by

the

macro

call

is

included

in

the

set

-RRB-

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-LCB-

-LRB-

M

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-LCB-

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-LCB-

load

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-RCB-

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-LCB-

move

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-RCB-

-RCB-

BRANCH

eq

-LRB-

A

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-RCB-

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-LCB-

load

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

move

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

BRANCH

eq

-LRB-

A

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-RCB-

Figure

Expansion

result

of

a

macro

call

Second

we

want

to

expand

the

following

call

of

the

macro

-LRB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

Observe

that

in

this

case

we

have

marked

two

auxiliary

registers

as

free

ones

The

expansion

result

is

now

shown

in

Figure

-LRB-

You

might

ond

it

interesting

to

try

to

ogure

out

by

yourself

what

would

happen

if

either

one

of

the

free

auxiliary

registers

were

replaced

with

the

accumulator

As

a

hint

we

give

the

fact

that

the

new

expansion

result

would

consist

of

six

system

macro

calls

-RRB-

-LRB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

load

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-RCB-

-LRB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

load

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-RCB-

-LRB-

R

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

store

-LRB-

R

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-RCB-

-RCB-

-LRB-

R

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

store

-LRB-

R

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-RCB-

-RCB-

-LRB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

load

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

load

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

store

-LRB-

R

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

store

-LRB-

R

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LCB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-RCB-

Figure

Expansion

result

of

a

macro

call

We

would

like

to

stress

the

crucial

point

of

the

expansion

result

shown

in

Figure

When

ReFlEx

tries

to

expand

the

-LRB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

call

at

the

orst

level

below

the

initial

call

it

recognizes

that

the

originally

free

auxiliary

register

R

-LSB-

-RSB-

is

not

free

any

more

Thus

R

-LSB-

-RSB-

is

the

only

possibility

for

a

temporary

storage

at

the

next-lower

level

This

deduction

rests

on

the

AEow-sensitivity

of

ReFlEx

Target

architecture

model

We

claim

that

even

the

rudimentary

ReFlEx

clearly

favors

some

important

common

features

of

low-cost

embedded

real-time

processors

such

as

the

DSPs

Typically

a

DSP

is

a

sequential

uniprocessor

i.e.

a

processor

with

a

single

instruction

stream

and

a

single

data

stream

Moreover

the

DSPs

are

prominent

ReFlEx

targets

especially

because

of

their

heterogeneous

register

set

Still

the

possible

targets

must

be

a

great

deal

simpler

than

any

real-world

processor?let

alone

any

of

DSPs

which

indeed

pose

exceptionally

diOEcult

problems

for

code

generators

-LSB-

-RSB-

The

most

notable

restriction

concerns

indirect

addressing

modes

which

are

completely

unsupported

by

ReFlEx

-LRB-

we

hope

that

in

forthcoming

releases

even

this

major

deociency

can

be

adequately

oxed

-RRB-

However

one

should

remember

that

with

many

processor

architectures

indirect

addressing

applies

only

to

memory

locations

and

not

to

CPU

registers

Code

storage

We

assume

that

there

is

only

a

single

instruction

stream

which

is

determined

by

the

contents

of

the

program

memory

Furthermore

the

program

memory

has

to

be

at

least

logically

both

unsegmented

and

separate

from

the

data

memory

Accordingly

the

program

counter

should

hold

full

program

memory

addresses

We

adopt

the

non-restrictive

convention

that

a

unique

instruction

label

is

associated

with

each

program

memory

location

Data

storage

We

assume

that

the

data

storage

is

divided

into

distinct

storage

classes

each

of

which

consists

of

a

onite

number

of

distinct

storage

cells

the

largest

storage

class

is

typically

constituted

by

the

data

memory

ReFlEx

expects

that

all

the

cells

in

a

single

storage

class

are

treated

fully

interchangeably

by

the

machine

instruction

set

if

an

occurrence

of

a

certain

instruction

refers

to

some

cell

other

occurrences

of

that

instruction

may

refer

to

any

cell

in

the

same

storage

class

The

size

i.e.

the

number

of

bit

positions

of

the

cells

in

a

particular

storage

class

is

irrelevant

to

ReFlEx

Accordingly

dioeerent

storage

classes

may

have

dioeerent

cell

sizes

but

ReFlEx

remains

unaware

of

this

dioeerence

ReFlEx

is

capable

of

automatic

intraclass?but

not

interclass?cell

allocation

The

division

of

labour

is

as

follows

the

human

programmer

chooses

the

optimum

storage

class

for

each

macro

temporary

and

ReFlEx

selects

an

appropriate

cell

from

the

chosen

class

In

particular

ReFlEx

usually

has

to

verify

that

the

selected

cell

is

free

at

the

point

of

the

macro

call

ReFlEx

is

not

capable

of

autonomously

spilling

a

non-free

register

into

memory

even

if

its

contents

will

be

needed

only

in

the

distant

future

and

a

register

of

that

class

is

immediately

needed

for

other

purposes

Because

such

a

spill

might

be

expensive

when

the

target

architecture

is

irregular

leaving

the

spill

decision

under

the

explicit

control

of

the

programmer

seems

to

be

sound

As

implicitly

expressed

above

in

regard

to

real-world

processor

architectures

our

concept

of

data

storage

has

two

major

drawbacks

ffl

Any

two

storage

cells

must

be

physically

distinct

that

is

they

can

not

overlap

ffl

Neither

hardware

nor

software

stack

is

supported

Comparison

with

real

machine

instruction

sets

ReFlEx

imposes

essential

restrictions

on

the

allowed

machine

instructions

of

the

target

architecture

Most

of

all

the

following

features

are

not

supported

ffl

Indirect

addressing

ffl

Indirect

jumps

ffl

Function

calls

ffl

Mode

control

ffl

VLIW-type

one-grained

parallelism

Of

the

diverse

addressing

modes

found

in

special-purpose

processors

only

direct

and

immediate

addressing

are

supported

Thus

instructions

may

only

explicitly

refer

to

certain

storage

cells

or

instruction

labels

or

explicitly

specify

certain

integer

values

If

indirect

addressing

of

storage

cells

were

allowed

it

would

pose

a

problem

in

the

data

AEow

analysis

because

the

macro

expander

would

then

have

to

keep

track

of

the

possible

values

of

the

address

registers

Similarly

enabling

indirect

jumps

would

complicate

the

control

AEow

analysis

In

high-level

programming

languages

such

as

C

functions

serve

two

purposes

they

provide

the

source

code

with

the

basic

structure

and

their

use

reduces

the

amount

of

memory

consumed

by

the

executable

code

Even

if

at

least

in

principle

the

ReFlEx

macros

meet

the

orst

one

of

these

two

goals

just

as

well

as

C

functions

their

careless

use

may

indeed

waste

memory

space

A

representative

example

of

mode

control

-LSB-

-RSB-

would

be

a

case

in

which

the

saturation

of

addition

operations

is

governed

by

a

status

register

whose

contents

the

programmer

may

modify

only

with

dedicated

instructions

Because

extraneous

instructions

are

seldom

cheap

the

programmer

must

carefully

keep

track

of

the

current

value

of

the

status

register

to

avoid

redundant

modiocation

instructions

This

task

could

clearly

be

automated

by

applying

program

AEow

analysis

but

ReFlEx

provides

no

explicit

support

for

mode

control

-LRB-

For

any

register

of

course

such

avoidance

of

redundant

loads

by

register

value

tracking

would

be

useful?ReFlEx

can

track

which

registers

are

in

use

but

not

their

contents

-RRB-

Very

long

instruction

word

-LRB-

VLIW

-RRB-

processors

-LSB-

-RSB-

contain

multiple

functional

units

that

may

all

be

independently

controlled

by

the

dioeerent

bit

oelds

of

a

single

instruction

word

Such

one-grained

parallelism

supports

fully

static

compilation-time

instruction

scheduling

which

is

in

many

cases

more

attractive

than

dynamic

execution-time

instruction

scheduling

-LRB-

performed

by

superscalar

processors

for

instance

-RRB-

In

this

fashion

individual

DSP

instructions

may

synchronously

drive

as

many

as

six

functional

units

which

include

an

arithmetic-logic

unit

and

a

hardware

multiplier

Programmer-controlled

pipelining

of

this

kind

is

perhaps

the

most

characteristic

feature

of

the

DSP

architectures

Our

machine

instruction

model

ReFlEx

assumes

that

the

machine

instructions

are

in

a

sense

independent

of

each

other

More

precisely

each

instruction

instance

should

explicitly

and

unambiguously

specify

ffl

the

set

of

storage

cells

it

reads

ffl

the

set

of

storage

cells

it

writes

and

ffl

the

set

of

instruction

labels

it

targets

that

is

the

labels

that

mark

the

program

memory

locations

to

one

of

which

the

control

is

transferred

after

its

execution

These

sets

may

be

empty

-LRB-

in

practice

even

an

instruction

implementing

an

empty

non-terminating

loop

may

be

handy

when

an

external

interrupt

is

waited

for

-RRB-

As

a

more

general

example

the

hypothetical

instruction

-LRB-

or

rather

system

macro

call

-RRB-

instance

BRANCH

probe

-LRB-

M

-LSB-

-RSB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

reads

cells

M

-LSB-

-RSB-

and

M

-LSB-

-RSB-

writes

cells

R

-LSB-

-RSB-

and

M

-LSB-

-RSB-

and

transfers

the

control

either

to

one

of

the

locations

labeled

and

or

to

the

location

immediately

following

the

instruction

instance

itself

-LRB-

or

loops

forever

-RRB-

In

eoeect

the

above

restriction

prevents

indirect

addressing

of

any

kind

In

addition

to

direct

addressing

only

immediate

addressing

is

enabled

instruction

instances

may

also

read

integer

literals

This

same

restriction

holds

for

application

macro

calls

which

are

identical

with

the

system

macro

calls

with

respect

to

the

syntax

and

semantics

of

the

caller-visible

interface

Our

meanings

for

the

words

read

and

write

are

perhaps

not

as

simple

as

one

might

hope

For

example

how

should

an

operation

described

by

the

C

language

statement

if

-LRB-

x

-RRB-

y

z

C

code

be

modeled

as

-LRB-

a

call

of

-RRB-

a

ReFlEx

system

macro

named

say

The

answer

is

-LRB-

x

y

z

y

-RRB-

and

the

explanation

is

as

follows

ffl

Clearly

this

instance

reads

x.

ffl

It

may

read

z.

Thus

z

should

not

be

inadvertently

corrupted

prior

to

the

operation

which

is

indicated

by

including

z

among

the

input

arguments

ffl

It

may

write

y

but

because

the

writing

may

not

take

place

even

y

should

not

be

corrupted

prior

to

the

operation

On

the

other

hand

the

longer

C

fragment

if

-LRB-

x

-RRB-

y

z

else

y

C

code

can

be

modeled

simply

as

-LRB-

x

z

y

-RRB-

This

distinction

may

at

orst

seem

confusing

but

fortunately

it

concerns

only

system

macro

implementors

They

have

to

create

a

sound

interface

between

ReFlEx

and

some

real

target

architecture

which

is

a

task

of

little

signiocance

in

the

case

of

the

purely

experimental

ReFlEx

The

application

macro

deonitions

in

contrast

can

be

verioed

in

this

respect

by

ReFlEx

itself

-LRB-

You

may

test

this

onal

claim

by

adding

an

application

macro

behaving

like

to

the

rule

ole

presented

in

Section

-RRB-

On

syntactical

conventions

Creating

a

ReFlEx

rule

ole

is

easier

if

you

are

aware

of

some

general

syntactical

conventions

many

of

which

resemble

the

ones

enforced

by

the

C

programming

language

-LSB-

-RSB-

However

a

notable

dioeerence

from

C

is

that

names

of

such

entities

that

will

be

introduced

only

later

in

the

rule

ole

may

freely

be

used

no

advance

declarations

whatsoever

are

needed

For

instance

the

storage

classes

may

be

referred

to

in

the

compound

form

deonitions

in

the

HEADER

part

which

must

precede

the

STORAGE

part

in

the

rule

ole

The

following

description

applies

both

to

the

rule

ole

and

to

the

expansion

source

Characters

Only

the

following

characters

are

recognized

ffl

Alphanumeric

characters

the

underscore

the

digits

the

uppercase

letters

A

Z

and

the

lowercase

letters

a

z

ffl

Special

characters

-LRB-

-RRB-

-LSB-

-RSB-

-LCB-

-RCB-

ffl

White

space

characters

space

horizontal

tab

and

newline

The

two-character

sequence

starts

a

comment

which

ends

with

the

end

of

the

current

line

C-style

multiline

comments

-LRB-

-RRB-

are

not

supported

Here

is

an

example

of

a

comment

-LRB-

a

b

-RRB-

This

is

a

comment

Other

characters

than

the

ones

listed

above

may

occur

only

inside

a

comment

White

space

characters

and

comments

are

collectively

called

white

space

Tokens

Each

occurrence

of

such

a

character

that

is

not

white

space

belongs

to

exactly

one

token

Actually

the

only

signiocance

of

white

space

is

that

it

is

often

-LRB-

but

not

always

-RRB-

necessary

for

separating

two

consecutive

tokens

This

function

of

white

space

becomes

apparent

with

the

following

deonition

Each

token

must

be

exactly

one

of

the

following

ffl

A

reserved

word

-LRB-

see

below

-RRB-

ffl

An

identioer

that

is

a

maximal

sequence

of

alphanumeric

characters

that

does

not

begin

with

a

digit

and

that

is

dioeerent

from

the

reserved

words

ffl

A

number

that

is

a

maximal

sequence

of

digits

that

is

not

immediately

preceded

by

any

other

alphanumeric

character

ffl

An

occurrence

of

a

special

character

The

distinction

between

upper

and

lower

case

is

signiocant

All

the

reserved

words

consist

of

uppercase

letters

only

-LRB-

contrary

to

the

C

convention

-RRB-

ASSERT

JUMP

STORAGE

BRANCH

NEXT

SYSTEM

HEADER

SAFE

TEST

INIT

SEED

THIS

INPUT

SLEEP

USE

INSIST

STATE

UTILITY

Here

are

three

examples

of

valid

identioers

assert

And

here

are

three

examples

of

valid

numbers

Structuring

mechanisms

Concerning

physical

structuring

such

ole

inclusion

as

performed

by

the

C

preprocessor

is

not

supported

by

ReFlEx

Furthermore

ReFlEx

does

not

allow

multiple

translation

units

-LRB-

as

C

does

-RRB-

Therefore

the

rule

ole

must

be

a

single

physical

ole

at

the

time

when

it

is

read

by

the

macro

expander

Concerning

logical

structuring

the

ReFlEx

syntax

employs

heavily

certain

special

character

pairs

as

list

delimiters

in

order

to

create

logical

hierarchy

in

the

rule

ole

Not

surprisingly

these

list

delimiter

pairs

are

-LRB-

-RRB-

-LSB-

-RSB-

and

-LCB-

-RCB-

Lists

generally

use

comma

as

an

element

separator

as

an

exception

certain

lists

delimited

by

curly

braces

employ

semicolon

as

an

element

terminator

Here

are

simple

examples

of

lists

-LRB-

a

b

c

-RRB-

-LSB-

a

b

c

-RSB-

-LCB-

a

b

c

-RCB-

-LCB-

a

b

c

-RCB-

Nevertheless

similarly

to

the

compound

statements

of

C

the

right

curly

brace

is

never

followed

by

a

semicolon

-LCB-

a

b

-LCB-

c

d

-RCB-

-RCB-

Finally

parenthesizing

arithmetic

expressions

is

not

a

problem

since

ReFlEx

provides

no

inox

operators

Parentheses

should

be

used

only

for

surrounding

argument

lists

of

macro

and

form

calls

For

instance

a

parenthesized

integer

literal

is

no

more

a

syntactically

valid

integer

designator

-LRB-

b

-RRB-

-LRB-

-LRB-

-RRB-

b

-RRB-

would

be

invalid

Constant

expressions

ReFlEx

includes

a

built-in

expansion-time

expression

interpreter

Using

a

simple

notation

you

may

deone

conventional

shorthands

for

complicated

arithmetic

expressions

Furthermore

the

interpreter

ooeers

you

certain

primitives

for

extracting

information

about

the

data

and

control

AEow

of

the

program

under

expansion

Why

do

we

need

such

an

interpreter

The

reason

is

that

ReFlEx

lacks

two

features

found

in

the

C

language

the

built-in

preprocessor

and

even

more

importantly

the

predeoned

set

of

-LRB-

relatively

-RRB-

machine-independent

run-time

operators

such

as

for

addition

and

for

multiplication

-LRB-

Most

macro

assemblers

provide

some

means

for

achieving

goals

similar

to

the

ones

of

our

interpreter

-RRB-

Let

us

have

an

example

Suppose

that

someone

asks

us

to

write

a

program

that

calculates

the

value

of

the

formula

for

any

x

and

y

given

that

the

values

of

a

and

b

are

and

respectively

First

we

produce

a

straightforward

C

implementation

z

x

y

C

code

Even

if

the

above

statement

looks

clumsy

it

is

an

eOEcient

one

because

the

predeoned

operator

is

a

part

of

the

C

deonition

the

C

compiler

can

be

expected

to

be

capable

of

folding

the

four

constants

into

one

-LSB-

Sec.

-RSB-

already

at

compilation

time

Furthermore

we

can

make

our

implementation

look

more

elegant

by

utilizing

the

C

preprocessor

#define

#define

#define

CUBE

-LRB-

a

-RRB-

-LRB-

-LRB-

a

-RRB-

-LRB-

a

-RRB-

-LRB-

a

-RRB-

-RRB-

#define

COEF

-LRB-

CUBE

-LRB-

-RRB-

-RRB-

z

COEF

x

y

C

code

Thus

in

the

case

of

C

having

predeoned

operators

enables

compile-time

constant

folding

while

the

preprocessor

makes

the

code

more

easily

readable

and

maintainable

With

ReFlEx

in

contrast

machine-independent

run-time

operators

are

ruled

out

for

ultimate

eOEciency

and

therefore

the

folding

of

constants

must

be

performed

by

the

expansion-time

expression

interpreter

It

is

also

our

intention

that

the

interpreter

should

be

able

to

handle

most

preprocessing-type

tasks

encountered

-LRB-

the

possibly

remaining

ones

of

these

tasks

have

to

be

relegated

to

a

fully

independent

text

preprocessor

-RRB-

As

an

instantaneous

preview

into

the

present

Section

we

provide

here

the

corresponding

ReFlEx

deonitions

for

the

above

C

preprocessor

deonitions

-LRB-

-RRB-

-LRB-

-RRB-

Cube

-LRB-

a

-RRB-

Mul

-LRB-

a

Mul

-LRB-

a

a

-RRB-

-RRB-

Coef

-LRB-

-RRB-

Mul

-LRB-

Cube

-LRB-

-LRB-

-RRB-

-RRB-

-LRB-

-RRB-

-RRB-

However

we

can

not

construct

a

similar

ReFlEx

deonition

that

would

match

the

C

preprocessor

deonition

that

next

comes

to

one

's

mind

#define

EXPR

-LRB-

x

y

-RRB-

-LRB-

COEF

-LRB-

x

-RRB-

-LRB-

y

-RRB-

-RRB-

C

code

The

reason

is

that

now

according

to

the

initial

assignment

given

to

us

the

multiplication

operators

represent

calculations

that

can

not

be

performed

until

execution

time

For

such

calculations

we

have

to

put

into

use

the

whole

ReFlEx

macro

deonition

facility

to

be

described

in

Section

Taxonomy

of

integer

cell

and

label

designators

An

expression

that

may

produce

an

integer

is

called

an

integer

designator

Integer

designators

are

divided

into

integer

literals

form

calls

and

integer

references

see

Sections

and

respectively

Correspondingly

there

are

cell

designators

and

label

designators

which

may

specify

-LRB-

storage

-RRB-

cells

and

-LRB-

instruction

-RRB-

labels

respectively

Cell

designators

are

divided

into

cell

literals

and

cell

references

and

label

designators

are

similarly

divided

into

label

literals

and

label

references

no

form

call

can

act

as

a

cell

or

label

designator

Cell

and

label

literals

can

only

be

used

in

the

expansion

source

-LRB-

see

Section

-RRB-

For

cell

and

label

references

see

Section

Whether

a

given

expression

is

an

integer

cell

or

label

designator

is

actually

a

property

of

each

particular

instance

of

the

expression

if

two

syntactically

identical

expression

instances

appear

in

dioeerent

contexts

it

may

be

that

only

one

of

them

is

a

valid

integer

designator

Furthermore

as

ReFlEx

classioes

the

designators

statically

already

before

the

macro

expansion

a

single

expression

instance

may

be

say

both

an

integer

designator

and

a

label

designator

Whether

such

an

ambiguous

designator

really

represents

an

object

of

the

kind

that

is

anticipated

by

the

dynamic

expansion

environment

can

not

generally

be

determined

until

expansion

time

Integer

literals

An

integer

literal

is

any

number

-LRB-

see

Section

-RRB-

optionally

preceded

by

arbitrarily

many

instances

of

special

characters

and

The

semantics

of

integer

literals

is

obvious

Here

are

ove

examples

of

valid

integer

literals

Form

calls

Form

calls

can

be

used

in

the

rule

ole

but

not

in

the

expansion

source

Each

form

call

is

evaluated

by

the

expansion-time

expression

interpreter

according

to

the

deonition

of

the

particular

form

There

is

a

small

set

of

predeoned

primitive

forms

which

consists

of

nine

autonomous

forms

and

six

contextsensitive

forms

Additionally

the

user

may

deone

new

compound

forms

in

the

HEADER

part

of

the

rule

ole

We

say

that

a

form

is

rigid

if

each

instance

of

the

form

call

requires

the

same

oxed

number

of

arguments

and

AEexible

if

its

calls

accept

any

number

of

arguments

Each

form

is

either

rigid

or

AEexible

Virtual

form

arguments

are

those

shown

in

the

form

calls

in

the

rule

ole

A

virtual

form

argument

can

be

an

integer

designator

a

cell

reference

or

a

label

reference

-LRB-

thus

cell

and

label

literals

are

ruled

out

-RRB-

Furthermore

a

macro

temporary

-LRB-

which

is

always

either

a

cell

reference

or

a

label

reference

-RRB-

can

never

be

used

as

a

virtual

form

argument

Actual

form

arguments

are

those

integers

cells

and

labels

that

replace

the

virtual

arguments

at

expansion

time

each

actual

argument

is

the

expansiontime

evaluation

result

of

the

corresponding

virtual

argument

-LRB-

When

we

use

the

plain

argument

we

usually

mean

an

actual

argument

the

exception

proving

this

rule

is

that

we

simply

say

an

argument

is

evaluated

with

the

obvious

interpretation

-RRB-

Next

in

Section

we

complete

the

characterization

of

the

possible

virtual

form

arguments

In

the

rest

of

the

present

Section

we

investigate

all

the

dioeerent

form

types

Integer

cell

and

label

references

Integer

references

are

identioers

or

reserved

words

that

possibly

represent

integers

There

are

the

following

types

of

integer

references

ffl

Each

input

parameter

of

a

macro

deonition

ffl

The

STATE

pocket

-LRB-

Pockets

can

only

be

employed

in

AEexible

compound

form

deonitions

see

Section

for

the

details

-RRB-

ffl

The

INPUT

pseudopocket

ffl

Each

auxiliary

pocket

Cell

references

are

identioers

or

reserved

words

that

possibly

represent

cells

There

are

the

following

types

of

cell

references

ffl

Each

data

parameter

of

a

macro

deonition

ffl

Each

data

temporary

of

a

macro

deonition

ffl

The

INPUT

pseudopocket

Label

references

are

identioers

or

reserved

words

that

possibly

represent

labels

There

are

the

following

types

of

label

references

ffl

Each

label

parameter

of

a

macro

deonition

ffl

Each

label

temporary

of

a

macro

deonition

ffl

The

INPUT

pseudopocket

ffl

Reserved

words

THIS

and

NEXT

-LRB-

These

can

only

be

employed

in

macro

deonitions

see

Section

for

the

details

-RRB-

As

specioed

above

reserved

word

INPUT

for

instance

is

in

an

appropriate

context

valid

as

an

integer

reference

as

a

cell

reference

and

as

a

label

reference

Such

conAEicts

can

not

be

resolved

until

expansion

time

Obviously

there

are

three

possible

cases

of

reference

mismatch

if

a

supposed

reference

to

an

integer

actually

turns

out

to

represent

a

non-integer

-LRB-

i.e.

a

cell

or

a

label

-RRB-

ReFlEx

simply

takes

zero

as

the

value

produced

by

the

reference

for

the

other

two

cases

see

Section

Autonomous

primitive

forms

All

autonomous

primitive

forms

are

rigid

Their

virtual

arguments

must

be

integer

designators

If

the

virtual

argument

still

at

expansion

time

turns

out

not

to

represent

an

integer

then

ReFlEx

uses

zero

as

the

actual

argument

The

autonomous

primitive

forms

can

be

divided

into

three

categories

ffl

Abort

-LRB-

x

y

z

-RRB-

which

raises

an

exception

ffl

If

-LRB-

x

y

z

-RRB-

which

implements

lazy

argument

evaluation

ffl

Arithmetic

primitive

forms

-LRB-

see

below

-RRB-

Instead

of

returning

each

call

of

Abort

aborts

the

expansion

immediately

No

expansion

result

is

produced

but

the

three

arguments

of

the

Abort

call

are

passed

to

the

user

as

an

explanation

The

If

-LRB-

x

y

z

-RRB-

call

is

processed

similarly

to

the

x?y

z

expression

of

the

C

language

That

is

the

following

steps

are

taken

The

orst

argument

is

evaluated

If

the

result

is

nonzero

the

second

argument

is

evaluated

and

the

resulting

value

is

returned

as

the

value

of

the

call

Otherwise

the

third

argument

is

evaluated

and

the

resulting

value

is

returned

as

the

value

of

the

call

Other

autonomous

primitive

forms

always

evaluate

all

their

arguments

but

either

the

second

or

the

third

argument

of

each

If

call

always

remains

unevaluated

Lazy

evaluation

of

this

kind

makes

even

recursive

compound

form

deonitions

feasible

There

are

in

all

seven

arithmetic

primitive

forms

which

are

shown

in

Table

The

rightmost

column

of

the

table

consists

of

C

language

expressions

These

expressions

ox

the

semantics

of

the

primitives

Still

the

precise

meaning

of

each

primitive

is

determined

only

by

the

particular

C

-LRB-

or

rather

C++

-RRB-

compiler

that

is

used

for

compiling

the

ReFlEx

source

code

including

in

particular

the

expressions

in

Table

-LRB-

see

also

Section

-RRB-

Add

-LRB-

x

y

-RRB-

addition

x

y

BNand

-LRB-

x

y

-RRB-

bitwise

NAND

-LRB-

x

y

-RRB-

BShl

-LRB-

x

y

-RRB-

bitwise

shift

-LRB-

y

-RRB-

-LRB-

x

y

-RRB-

-LRB-

x

y

-RRB-

Div

-LRB-

x

y

-RRB-

division

x

y

Lt

-LRB-

x

y

-RRB-

less-than

-LRB-

x

y

-RRB-

Mul

-LRB-

x

y

-RRB-

multiplication

x

y

Nand

-LRB-

x

y

-RRB-

logical

NAND

-LRB-

x

y

-RRB-

Table

Arithmetic

primitive

forms

We

also

give

brief

verbal

descriptions

for

the

arithmetic

primitive

forms

Add

-LRB-

x

y

-RRB-

Addition

of

the

two

arguments

BNand

-LRB-

x

y

-RRB-

Bitwise

NAND

operation

BShl

-LRB-

x

y

-RRB-

The

bitwise

representation

of

x

is

shifted

to

the

left

by

y

positions

if

y

is

positive

and

otherwise

to

the

right

by

y

positions

Div

-LRB-

x

y

-RRB-

Division

of

x

by

y.

Lt

-LRB-

x

y

-RRB-

If

x

is

less

than

y

is

returned

otherwise

is

returned

Mul

-LRB-

x

y

-RRB-

Multiplication

of

the

two

arguments

Nand

-LRB-

x

y

-RRB-

Logical

NAND

operation

that

results

in

either

or

Context-sensitive

primitive

forms

The

virtual

arguments

of

context-sensitive

primitive

forms

must

be

cell

or

label

references

However

if

any

virtual

argument

turns

out

to

represent

an

integer

then

the

whole

form

call

is

taken

to

return

zero

The

same

happens

if

an

expected

storage

cell

turns

out

to

be

an

instruction

label

or

vice

versa

-LRB-

Thus

one

could

say

that

type

checking

is

here

somewhat

stricter

than

with

autonomous

primitives

-RRB-

Except

for

-LRB-

-RRB-

all

the

context-sensitive

primitives

are

AEexible

There

is

an

implicit

conjunction

between

the

arguments

of

any

AEexible

context-sensitive

primitive

For

instance

the

M

-LRB-

x

-RRB-

form

call

checks

whether

x

represents

a

cell

that

belongs

to

storage

class

M

and

M

-LRB-

x

y

z

-RRB-

checks

whether

all

three

of

x

y

and

z

belong

to

M

A

form

call

inside

a

macro

deonition

produces

always

the

same

result

that

would

have

been

obtained

if

an

identical

form

call

had

been

evaluated

as

a

macro-specioc

test

of

the

current

macro

-LRB-

see

Section

-RRB-

Remember

also

that

macro

temporaries

can

not

be

used

as

virtual

form

arguments

There

are

six

context-sensitive

primitive

forms

most

of

which

may

be

further

parametrized

with

a

storage

class

specioer

-LRB-

such

as

M

of

the

M

-LRB-

x

-RRB-

form

call

above

-RRB-

The

use

of

the

context-sensitive

primitives

is

explained

below

the

individual

form

descriptions

are

followed

by

a

concise

summary

Are

the

arguments

cells

-LRB-

of

a

particular

storage

class

-RRB-

The

-LRB-

-RRB-

form

is

AEexible

It

returns

if

all

the

arguments

are

storage

cells

and

otherwise

Examples

-LRB-

x

-RRB-

Does

x

represent

a

cell

-LRB-

x

y

z

-RRB-

Do

x

y

and

z

all

represent

cells

-LRB-

-RRB-

Trivially

is

returned

A

-LRB-

x

-RRB-

Does

x

represent

a

cell

that

belongs

to

storage

class

A

Are

the

arguments

similar

cells

The

-LRB-

-RRB-

form

is

AEexible

It

returns

if

all

the

arguments

are

storage

cells

belonging

to

a

common

storage

class

and

otherwise

Examples

-LRB-

x

y

z

-RRB-

Do

x

y

and

z

represent

cells

that

belong

to

some

single

common

storage

class

A

-LRB-

x

y

-RRB-

The

same

as

A

-LRB-

x

y

-RRB-

Are

the

argument

cells

the

same

The

=-LRB-

-RRB-

form

is

AEexible

It

returns

if

all

the

arguments

are

identical

cells

and

otherwise

-LRB-

It

can

not

be

used

in

safety

declarations

see

Section

-RRB-

Examples

-LRB-

x

y

z

-RRB-

Do

x

y

and

z

all

represent

the

same

cell

A

-LRB-

x

y

-RRB-

Do

x

and

y

represent

a

single

common

cell

of

storage

class

A

Are

the

arguments

free

cells

The

-LRB-

-RRB-

form

is

AEexible

It

returns

if

all

the

arguments

are

free

storage

cells

and

otherwise

-LRB-

It

can

not

be

used

in

safety

declarations

see

Section

-RRB-

For

the

deonition

of

a

free

cell

see

Section

Examples

-LRB-

x

y

z

-RRB-

Do

x

y

and

z

all

represent

free

cells

A

-LRB-

x

-RRB-

Does

x

represent

a

free

cell

of

storage

class

A

How

many

free

cells

are

there

The

-LRB-

-RRB-

form

is

rigid

and

expects

no

arguments

It

returns

the

number

of

distinct

free

storage

cells

-LRB-

It

can

not

be

used

in

safety

declarations

see

Section

-RRB-

Examples

-LRB-

-RRB-

How

many

free

cells

are

there

A

-LRB-

-RRB-

How

many

free

cells

of

storage

class

A

are

there

Are

the

argument

labels

the

same

The

-LRB-

-RRB-

form

is

AEexible

It

returns

if

all

the

arguments

are

equivalent

instruction

labels

and

otherwise

It

does

not

accept

a

storage

class

specioer

The

reserved

words

THIS

and

NEXT

are

label

references

that

can

be

used

as

virtual

arguments

of

this

form

THIS

represents

the

label

of

the

current

macro

call

whereas

NEXT

represents

the

label

that

immediately

follows

the

current

macro

call

Thus

the

code

produced

from

the

current

macro

call

will

be

located

between

these

two

labels

Label

references

can

be

fully

resolved

only

at

the

onal

stage

of

the

expansion

Consequently

ReFlEx

must

be

conservative

in

its

decisions

even

if

such

a

call

as

-LRB-

x

y

-RRB-

returns

it

may

still

be

so

that

x

and

y

actually

represent

equivalent

labels

However

most

importantly

if

the

call

returns

then

the

arguments

are

guaranteed

to

be

equivalent

Examples

-LRB-

x

y

z

-RRB-

Do

x

y

and

z

all

represent

equivalent

labels

-LRB-

x

-RRB-

Does

x

represent

a

label

-LRB-

x

THIS

-RRB-

Does

x

represent

the

label

of

the

orst

instruction

of

the

code

segment

resulting

from

the

current

macro

call

Summary

of

context-sensitive

primitive

forms

In

Table

we

summarize

the

use

of

the

context-sensitive

primitive

forms

From

the

table

you

see

that

all

these

forms

except

-LRB-

-RRB-

accept

a

storage

class

specioer

Other

forms

than

-LRB-

-RRB-

are

AEexible

Of

the

AEexible

forms

-LRB-

-RRB-

expects

labels

for

arguments

whereas

the

others

expect

cells

The

rigid

-LRB-

-RRB-

takes

no

arguments

and

returns

a

non-negative

integer

Other

forms

than

-LRB-

-RRB-

return

either

zero

or

one

Finally

forms

=-LRB-

-RRB-

-LRB-

-RRB-

and

-LRB-

-RRB-

can

not

be

employed

in

safety

declarations

Cells

-LRB-

-RRB-

class

-LRB-

-RRB-

cells

or

SAFE

Similar

cells

-LRB-

-RRB-

class

-LRB-

-RRB-

cells

or

SAFE

Same

cell

=-LRB-

-RRB-

class

-LRB-

-RRB-

cells

or

Free

cells

-LRB-

-RRB-

class

-LRB-

-RRB-

cells

or

How

many

free

cells

-LRB-

-RRB-

#class

-LRB-

-RRB-

n

Equivalent

labels

-LRB-

-RRB-

labels

or

SAFE

Table

Context-sensitive

primitive

forms

Rigid

compound

forms

Two

most

simple

rigid

compound

form

deonitions

read

as

follows

Dozen

-LRB-

-RRB-

Gross

-LRB-

-RRB-

Mul

-LRB-

Dozen

-LRB-

-RRB-

Dozen

-LRB-

-RRB-

-RRB-

More

complicated

deonitions

are

of

course

possible

Sub

-LRB-

x

y

-RRB-

Add

-LRB-

x

Add

-LRB-

BNand

-LRB-

y

y

-RRB-

-RRB-

-RRB-

The

above

deonition

of

subtraction

captures

precisely

the

details

of

the

two

's

complement

representation

for

negative

integers

-LRB-

It

is

often

important

to

be

able

to

faithfully

emulate

the

operation

of

the

target

processor

already

at

expansion

time

Still

the

host

processor

which

executes

the

macro

expander

program

may

support

a

dioeerent

representation

in

that

case

we

are

likely

to

need

two

subtraction

variants?one

for

each

processor

Actually

it

seems

natural

that

the

host

subtraction

would

be

the

one

more

heavily

utilized

-RRB-

As

the

orst

stage

of

the

evaluation

of

a

call

of

a

rigid

compound

form

and

therefore

even

before

the

evaluation

of

the

arguments

the

interpreter

replaces

the

call

with

the

deonition

of

the

form

called

This

strategy

supports

lazy

evaluation

because

the

deonition

may

consist

of

an

If

call

Rigid

compound

forms

may

be

recursive

again

because

of

the

special

property

of

the

If

form

Here

is

a

recursive

deonition

for

the

factorial

function

Fact

-LRB-

x

-RRB-

If

-LRB-

Lt

-LRB-

x

-RRB-

Mul

-LRB-

x

Fact

-LRB-

Sub

-LRB-

x

-RRB-

-RRB-

-RRB-

-RRB-

It

is

often

convenient

to

hide

the

autonomous

primitive

forms

inside

a

separate

module

whose

settings

can

be

easily

revised

if

necessary

-LRB-

In

particular

we

might

need

say

a

target

multiplication

in

addition

to

the

predeoned

host

multiplication

for

an

explanation

see

the

above

discussion

on

subtraction

variants

-RRB-

Accordingly

we

redeone

the

autonomous

primitives

-LRB-

note

especially

the

deonition

of

Div

-RRB-

Abort

-LRB-

x

y

z

-RRB-

Abort

-LRB-

x

y

z

-RRB-

If

-LRB-

x

y

z

-RRB-

If

-LRB-

x

y

z

-RRB-

Add

-LRB-

x

y

-RRB-

Add

-LRB-

x

y

-RRB-

BNand

-LRB-

x

y

-RRB-

BNand

-LRB-

x

y

-RRB-

BShl

-LRB-

x

y

-RRB-

BShl

-LRB-

x

y

-RRB-

Div

-LRB-

x

y

-RRB-

If

-LRB-

y

Div

-LRB-

x

y

-RRB-

Abort

-LRB-

x

y

-RRB-

-RRB-

Lt

-LRB-

x

y

-RRB-

Lt

-LRB-

x

y

-RRB-

Mul

-LRB-

x

y

-RRB-

Mul

-LRB-

x

y

-RRB-

Nand

-LRB-

x

y

-RRB-

Nand

-LRB-

x

y

-RRB-

With

a

few

more

deonitions

we

can

extend

our

collection

of

basic

forms

into

a

fairly

useful

one

Not

-LRB-

x

-RRB-

Nand

-LRB-

x

x

-RRB-

Lte

-LRB-

x

y

-RRB-

Not

-LRB-

Lt

-LRB-

y

x

-RRB-

-RRB-

Gt

-LRB-

x

y

-RRB-

Lt

-LRB-

y

x

-RRB-

Gte

-LRB-

x

y

-RRB-

Lte

-LRB-

y

x

-RRB-

Eq

-LRB-

x

y

-RRB-

If

-LRB-

Gte

-LRB-

x

y

-RRB-

Gte

-LRB-

y

x

-RRB-

-RRB-

Neq

-LRB-

x

y

-RRB-

Not

-LRB-

Eq

-LRB-

x

y

-RRB-

-RRB-

In

Figure

we

deone

some

auxiliary

forms

that

are

utilized

in

the

macro

deonition

examples

of

Appendix

C

As

you

can

see

we

use

as

building

blocks

even

some

context-sensitive

primitive

forms

in

addition

to

the

autonomous

ones

We

assume

that

the

available

storage

classes

are

M

R

and

A

-LRB-

as

shown

in

Figure

on

page

-RRB-

We

give

some

comments

concerning

these

auxiliary

forms

Int

checks

whether

its

argument

is

an

integer

-LRB-

that

is

neither

a

cell

nor

a

label

-RRB-

Type

tells

its

caller

exactly

which

kind

of

object

its

argument

is

Ordered

can

be

very

useful

in

normalizing

the

order

of

macro

arguments

as

you

can

see

by

examining

the

macro

deonitions

in

Appendix

C.

Int

-LRB-

x

-RRB-

If

-LRB-

-LRB-

x

-RRB-

If

-LRB-

-LRB-

x

-RRB-

-RRB-

-RRB-

Type

-LRB-

x

-RRB-

If

-LRB-

A

-LRB-

x

-RRB-

If

-LRB-

R

-LRB-

x

-RRB-

If

-LRB-

M

-LRB-

x

-RRB-

If

-LRB-

Int

-LRB-

x

-RRB-

-RRB-

-RRB-

-RRB-

-RRB-

Ordered

-LRB-

x

y

-RRB-

If

-LRB-

If

-LRB-

Int

-LRB-

x

-RRB-

Int

-LRB-

y

-RRB-

-RRB-

Lte

-LRB-

x

y

-RRB-

Lte

-LRB-

Type

-LRB-

x

-RRB-

Type

-LRB-

y

-RRB-

-RRB-

-RRB-

Figure

Deonitions

of

some

auxiliary

forms

Flexible

compound

forms

Flexible

compound

form

deonitions

have

to

be

somewhat

more

complicated

than

the

ones

for

rigid

compound

forms

because

of

the

variable

number

of

arguments

-LRB-

In

contrast

there

are

no

dioeerences

in

the

call

syntax

-RRB-

Our

orst

AEexible

compound

form

is

the

logical

disjunction

Or

-LCB-

SEED

STATE

If

-LRB-

STATE

INPUT

-RRB-

-RCB-

This

Or

deonition

consists

of

the

subdeonitions

of

two

pockets

SEED

and

STATE

in

general

these

two

subdeonitions

in

this

order

are

obligatory

By

a

pocket

we

denote

a

store

capable

of

holding

an

integer

at

expansion

time

In

addition

to

these

two

pockets

in

the

STATE

subdeonition

the

INPUT

pseudopocket

is

referred

to

The

volatile

INPUT

pseudopocket

points

to

each

form

argument

in

turn

Thus

it

may

represent

cells

and

labels

as

well

as

integers

An

Or

call

is

evaluated

according

to

the

following

procedure

-LRB-

which

is

applied

to

each

call

of

each

AEexible

compound

form

-RRB-

The

integer

designator

that

constitutes

the

SEED

subdeonition

is

evaluated

and

the

resulting

value

is

copied

into

the

STATE

pocket

-LRB-

as

you

see

the

SEED

pocket

itself

is

actually

redundant

-RRB-

From

left

to

right

for

each

argument

of

the

original

call

the

integer

designator

that

constitutes

the

STATE

subdeonition

is

evaluated

according

to

the

following

subprocedure

-LRB-

a

-RRB-

Each

reference

to

the

STATE

pocket

is

-LRB-

temporarily

-RRB-

replaced

with

the

current

contents

of

STATE

-LRB-

b

-RRB-

If

there

are

one

or

more

references

to

the

INPUT

pocket

that

must

be

evaluated

-LRB-

note

that

even

If

through

If

implements

lazy

evaluation

-RRB-

then

the

current

argument

of

the

original

call

is

evaluated

and

the

references

to

INPUT

are

-LRB-

temporarily

-RRB-

replaced

with

the

resulting

object

-LRB-

which

is

an

integer

a

cell

or

a

label

-RRB-

-LRB-

c

-RRB-

The

integer

that

results

from

the

evaluation

of

the

whole

modioed

STATE

subdeonition

is

put

in

the

STATE

pocket

-LRB-

thus

the

old

value

of

the

pocket

is

lost

-RRB-

The

evaluation

result

of

the

original

form

call

is

determined

by

the

onal

value

of

the

STATE

pocket

It

should

be

noted

that

the

above

Or

deonition

would

represent

logical

disjunction

even

if

the

references

to

the

STATE

pocket

and

to

the

INPUT

pseudopocket

in

the

STATE

subdeonition

were

interchanged

However

if

the

change

took

place

all

the

arguments

of

each

Or

call

would

always

have

to

be

evaluated

The

deonition

of

the

logical

conjunction

And

is

fairly

similar

to

the

Or

deonition

And

-LCB-

SEED

STATE

If

-LRB-

STATE

INPUT

-RRB-

-RCB-

Next

we

deone

a

AEexible

form

that

examines

whether

its

arguments

are

all

integers

The

Const

deonition

closely

resembles

the

And

deonition

above

Const

-LCB-

SEED

STATE

If

-LRB-

STATE

Int

-LRB-

INPUT

-RRB-

-RRB-

-RCB-

In

addition

the

SEED

and

STATE

pockets

the

user

may

deone

new

pockets

Such

auxiliary

pockets

are

always

zero-initialized

and

they

are

updated

in

parallel

and

fully

synchronously

with

the

STATE

pocket

Our

last

form

in

Figure

checks

whether

all

of

its

arguments

are

equal

integers

This

Equal

definition

uses

two

auxiliary

pockets

later

and

value

-LRB-

later

indicates

whether

the

current

argument

is

a

non-orst

one

and

value

holds

the

value

of

the

orst

argument

-RRB-

Equal

-LCB-

SEED

STATE

If

-LRB-

STATE

If

-LRB-

later

And

-LRB-

Const

-LRB-

INPUT

-RRB-

Eq

-LRB-

value

INPUT

-RRB-

-RRB-

Const

-LRB-

INPUT

-RRB-

-RRB-

-RRB-

later

value

If

-LRB-

later

value

INPUT

-RRB-

-RCB-

Figure

Deonition

of

the

Equal

AEexible

compound

form

Finally

we

collect

the

main

points

you

should

remember

when

deoning

AEexible

compound

forms

ffl

The

SEED

and

STATE

subdeonitions

in

this

order

are

obligatory

after

them

you

may

introduce

auxiliary

pockets

Furthermore

there

is

also

the

predeoned

INPUT

pseudopocket

ffl

In

the

SEED

subdeonition

no

pocket

can

be

referred

to

Conversely

the

SEED

pocket

itself

can

not

be

referred

to

in

any

pocket

subdeonition

ffl

The

initial

value

of

the

STATE

pocket

is

determined

by

the

SEED

subdefinition

and

the

initial

value

of

each

auxiliary

pocket

is

ffl

For

each

form

argument

the

STATE

pocket

and

the

possible

auxiliary

pockets

are

updated

in

parallel

and

fully

synchronously

Macro

deonitions

As

depicted

already

in

Figure

on

page

a

ReFlEx

rule

ole

consists

of

four

main

parts

HEADER

-LCB-

-RCB-

STORAGE

-LCB-

-RCB-

SYSTEM

-LCB-

-RCB-

UTILITY

-LCB-

-RCB-

In

this

section

we

concentrate

on

the

UTILITY

part

which

contains

the

application

macro

deonitions

Additionally

the

system

macro

declarations

of

the

SYSTEM

part

can

be

seen

as

reduced

variants

of

application

macro

deonitions

the

dioeerences

are

described

in

Section

The

compound

form

deonitions

of

the

HEADER

part

were

discussed

in

Sections

and

In

this

and

the

forthcoming

sections

we

assume

that

all

the

forms

of

Section

are

deoned

in

our

HEADER

part

Furthermore

we

assume

the

STORAGE

part

deoned

in

Figure

on

page

we

have

an

accumulator

A

four

auxiliary

registers

R

-LSB-

-RSB-

R

-LSB-

-RSB-

and

data

memory

locations

M

-LSB-

-RSB-

M

-LSB-

-RSB-

Finally

we

also

assume

the

SYSTEM

part

shown

in

Figure

on

page

In

this

section

our

examples

are

short

and

simple

slightly

more

elaborate

macro

deonitions

can

be

seen

in

Appendix

C

We

adopt

the

convention

that

any

macro

whose

name

begins

with

a

t

preox

is

only

for

a

momentary

use

Often

no

deonition

is

provided

for

such

a

macro

General

structure

of

a

macro

deonition

The

UTILITY

part

of

a

ReFlEx

rule

ole

consists

of

a

sequence

of

macro

deonitions

-LRB-

whose

mutual

order

is

insigniocant

-RRB-

The

general

structure

of

such

a

deonition

is

shown

in

Figure

As

indicated

in

the

ogure

some

of

the

items

are

optional

The

meaning

of

the

items

in

Figure

is

as

follows

deviation

Is

the

macro

a

branch

of

any

kind

See

Section

name

Name

of

the

macro

being

deoned

params

Macro

parameters

-LRB-

which

represent

integers

storage

cells

and

instruction

labels

-RRB-

See

Section

deviationopt

name

params

-LCB-

safetyopt

testopt

tempopt

version

version

assertionopt

version

insistopt

version

-RCB-

Figure

Structure

of

a

macro

deonition

safety

Safety

declaration

-LRB-

a

promise

by

the

macro

writer

-RRB-

See

Section

test

Macro-specioc

test

clause

See

Section

temp

Declaration

of

macro-specioc

temporaries

See

Section

version

Deonition

of

a

macro

version

See

Section

assertion

An

assertion

clause

See

Section

insist

An

insist

clause

See

Section

The

macro

deonition

can

be

divided

into

the

following

parts

ffl

The

macro

exterior

contains

the

deviation

name

params

safety

and

test

items

It

can

be

seen

as

the

external

interface

of

the

macro

The

macro

head

is

a

subset

of

the

macro

exterior

It

consists

of

the

deviation

name

and

params

items

ffl

The

macro

interior

contains

the

temp

version

assertion

and

insist

items

It

can

be

seen

as

the

internal

implementation

of

the

macro

Here

is

a

simple

macro

deonition

which

contains

a

single

version

JUMP

-LRB-

a

c

-RRB-

-LSB-

-RSB-

-LCB-

TEST

And

-LRB-

A

-LRB-

a

-RRB-

Const

-LRB-

c

-RRB-

-RRB-

USE

R

-LSB-

-RSB-

M

-LSB-

-RSB-

implem

-LCB-

-LRB-

a

c

-RRB-

JUMP

-LRB-

-RRB-

-LSB-

-RSB-

-RCB-

-RCB-

If

a

macro

deonition

includes

several

alternative

versions

they

must

be

listed

in

the

order

of

decreasing

priority

at

expansion

time

ReFlEx

traverses

through

the

versions

in

the

order

specioed

by

the

macro

writer

System

macros

The

SYSTEM

part

of

the

rule

ole

contains

the

system

macro

declarations

-LRB-

see

Figure

on

page

for

an

example

-RRB-

A

system

macro

declaration

consists

of

a

macro

exterior

only

BRANCH

eq

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-LCB-

TEST

A

-LRB-

a

-RRB-

-RCB-

However

unlike

an

application

macro

exterior

a

system

macro

declaration

can

not

contain

a

safety

declaration

-LRB-

see

Section

-RRB-

-LRB-

Here

the

macro

language

designer

had

to

choose

between

simplicity

and

uniformity

and

simplicity

was

chosen

-RRB-

Control

transfer

Concerning

the

control

transfer

after

execution

ReFlEx

macros

are

for

code

readability

divided

into

four

types

by

three

distinct

deviation

qualioers

All

these

qualioers

can

be

found

in

the

macro

calls

shown

in

Figure

-LRB-

x

y

-RRB-

BRANCH

-LRB-

x

y

-RRB-

-LSB-

-RSB-

JUMP

-LRB-

x

y

-RRB-

-LSB-

-RSB-

SLEEP

-LRB-

x

y

-RRB-

Figure

The

deviation

qualioers

Macros

of

the

BRANCH

and

JUMP

types

are

the

only

ones

that

can

transfer

the

control

to

a

remote

location

-LRB-

specioed

by

a

label

parameter

-RRB-

macros

of

the

default

and

BRANCH

types

are

the

only

ones

that

can

transfer

the

control

to

the

location

immediately

following

-LRB-

the

code

resulting

from

-RRB-

the

macro

call

itself

Thus

BRANCH

and

JUMP

macros

are

conditional

and

unconditional

branches

respectively

whereas

SLEEP

macros

can

represent

non-terminating

loops

Supposing

that

the

macro

calls

in

Figure

constitute

a

code

fragment

the

call

would

be

unreachable

if

it

were

not

provided

with

the

label

temporary

Each

macro

call

instance

must

be

explicitly

provided

with

the

same

deviation

qualioer

that

is

specioed

already

in

the

deonition

of

the

particular

macro

Macro

parameters

and

arguments

Macro

variables

are

divided

into

parameters

and

temporaries

-LRB-

for

the

temporaries

see

Section

-RRB-

Because

ReFlEx

does

not

support

global

variables

macro

parameters

are

the

only

means

for

passing

information

across

macro

boundaries

at

execution

time

There

are

both

data

parameters

and

label

parameters

A

data

parameter

may

be

an

input

one

an

output

one

or

an

input-output

one

Label

parameters

represent

branch

targets

The

macro

head

specioes

the

parameters

We

present

some

examples

in

Figure

-LRB-

x

y

x

y

z

-RRB-

-LCB-

-RCB-

BRANCH

-LRB-

i

j

-RRB-

-LSB-

l

l

m

-RSB-

-LCB-

-RCB-

-LRB-

s

-RRB-

-LCB-

-RCB-

JUMP

-LRB-

-RRB-

-LSB-

t

-RSB-

-LCB-

-RCB-

Figure

Declarations

of

macro

parameters

Note

the

following

concerning

the

examples

in

Figure

ffl

Output

parameters

are

separated

from

input

ones

by

the

special

character

which

divides

the

data

parameter

list

into

two

sublists

Understandably

input-output

parameters

must

occur

in

both

these

sublists

y

is

an

input-output

parameter

of

The

separator

is

omitted

if

there

are

neither

output

nor

input-output

parameters

ffl

If

there

are

no

label

parameters

the

label

parameter

list

is

omitted

In

contrast

even

if

there

are

no

data

parameters

an

empty

data

parameter

list

must

still

be

present

ffl

Parameter

x

appears

twice

in

the

input

parameter

sublist

of

and

parameter

l

appears

twice

in

the

label

parameter

list

of

No

parameter

should

appear

twice

in

an

output

parameter

sublist

duplicate

input

or

label

parameters

are

seldom

useful

although

they

are

fully

supported

by

ReFlEx

ffl

For

each

macro

deonition

the

set

of

data

parameters

and

the

set

of

label

parameters

must

be

distinct

When

a

macro

is

called

macro

arguments

stand

for

the

macro

parameters

With

macro

arguments

we

do

not

employ

such

a

special

notion

as

the

notion

of

an

input-output

parameter

with

macro

parameters?an

output

argument

may

simply

simultaneously

be

even

an

input

argument

When

a

macro

is

called

inside

a

deonition

of

another

macro

the

macro

writer

provides

the

call

with

virtual

arguments

that

represent

the

actual

arguments

i.e.

integers

storage

cells

and

instruction

labels

The

virtual

arguments

must

meet

the

following

constraints

ffl

A

label

parameter

must

be

matched

by

a

label

variable

-LRB-

the

reserved

words

THIS

and

NEXT

can

not

do

-RRB-

ffl

In

general

a

data

parameter

must

be

matched

by

a

data

variable

alternatively

an

input

-LRB-

but

not

an

input-output

-RRB-

parameter

may

be

matched

by

an

integer

designator

Not

surprisingly

if

a

parameter

appears

multiple

times

in

the

parameter

lists

the

corresponding

actual

arguments

should

also

be

identical

The

satisfaction

of

this

constraint

is

not

verioed

until

expansion

time?the

corresponding

virtual

arguments

need

not

be

identical

Here

we

provide

sample

calls

for

the

macros

of

Figure

-LRB-

a

Add

-LRB-

-RRB-

a

b

-RRB-

BRANCH

-LRB-

u

v

-RRB-

-LSB-

k

k

k

-RSB-

-LRB-

a

-RRB-

JUMP

-LRB-

-RRB-

-LSB-

k

-RSB-

Structure

of

a

version

deonition

The

macro

deonition

contains

an

ordered

sequence

of

version

deonitions

optionally

there

may

also

be

assertion

clauses

or

insist

clauses

between

the

version

deonitions

-LRB-

see

Section

-RRB-

The

overall

structure

of

each

version

deonition

is

shown

in

Figure

name

testopt

tempopt

-LCB-

statement

statement

-RCB-

Figure

Structure

of

a

version

deonition

The

meaning

of

the

items

in

Figure

is

as

follows

name

Name

of

the

version

being

deoned

-LRB-

This

name

is

more

like

a

comment

it

is

never

referred

to

-RRB-

test

Version-specioc

test

clause

See

Section

temp

Declaration

of

version-specioc

temporaries

See

Section

stmt

A

statement

See

below

A

statement

consists

of

a

unique

label

temporary

a

macro

or

pseudomacro

call

-LRB-

for

pseudomacros

see

Section

-RRB-

and

a

terminating

semicolon

Both

the

temporary

and

the

call

are

optional

A

statement

is

empty

if

it

does

not

contain

a

macro

-LRB-

or

pseudomacro

-RRB-

call

The

statement

sequence

of

a

version

deonition

is

called

the

version

body

Simple

examples

of

version

deonitions

can

be

found

for

instance

in

Figure

in

Section

and

in

Figure

in

Section

Test

assertion

and

insist

clauses

Sometimes

the

user

needs

to

tell

ReFlEx

explicitly

whether

it

should

or

should

not

take

a

particular

course

of

action

at

expansion

time

A

directive

of

this

kind

is

typically

a

conditional

one

the

course

should

be

taken

if

and

only

if

a

given

constraint

is

satisoed

Such

constraints

can

be

represented

by

integer

designators

by

convention

the

constraint

is

taken

as

being

satisoed

if

the

integer

designator

evaluates

to

a

nonzero

value

The

user

writes

conditional

directives

by

inserting

the

constraint

in

an

appropriate

clause

If

the

constraint

of

the

clause

is

satisoed

we

say

that

the

clause

itself

is

also

satisoed

In

a

macro

deonition

you

may

ond

four

dioeerent

types

of

clauses

macro-specioc

test

clauses

-LRB-

TEST

-RRB-

version-specioc

test

clauses

-LRB-

TEST

again

-RRB-

assertion

clauses

-LRB-

ASSERT

-RRB-

and

insist

clauses

-LRB-

INSIST

-RRB-

In

Figure

we

show

all

the

four

clause

types

In

the

deonition

there

is

a

macro-specioc

test

two

version-specioc

tests

a

single

assertion

and

a

single

insist

-LRB-

x

y

-RRB-

-LCB-

TEST

And

-LRB-

Or

-LRB-

A

-LRB-

y

-RRB-

R

-LRB-

y

-RRB-

-RRB-

Gte

-LRB-

R

-LRB-

-RRB-

-RRB-

-RRB-

USE

R

-LSB-

t

-RSB-

TEST

A

-LRB-

y

-RRB-

USE

R

-LSB-

u

-RSB-

-LCB-

-LRB-

x

t

u

-RRB-

-LRB-

t

u

y

-RRB-

-RCB-

INSIST

Not

-LRB-

A

-LRB-

y

-RRB-

-RRB-

TEST

R

-LRB-

y

-RRB-

-LCB-

-LRB-

x

t

y

-RRB-

-LRB-

t

y

y

-RRB-

-RCB-

ASSERT

-RCB-

Figure

The

dioeerent

clause

types

The

meaning

of

the

clauses

is

as

follows

ffl

The

macro-specioc

test

determines

whether

a

call

of

the

current

macro

is

acceptable

as

a

part

of

the

expansion-time

realization

of

an

upper-level

macro

call

ffl

The

version-specioc

test

determines

whether

the

particular

macro

version

can

be

considered

as

an

expansion-time

realization

of

a

call

of

the

current

macro

-LRB-

Even

if

the

clause

is

satisoed

the

version

will

be

rejected

if

ReFlEx

can

not

allocate

cells

for

the

data

variables

of

the

version

or

if

the

macro-specioc

tests

of

the

macros

called

in

the

version

body

can

not

be

satisoed

-RRB-

ffl

During

the

version

selection

if

ReFlEx

reaches

an

assertion

that

is

not

satisoed

the

whole

expansion

is

immediately

aborted

and

an

error

message

is

issued

Furthermore

no

expansion

result

-LRB-

not

even

a

failing

one

-RRB-

is

produced

ffl

During

the

version

selection

if

ReFlEx

reaches

an

insist

that

is

not

satisoed

the

reonement

of

the

current

macro

call

fails

as

if

there

were

no

more

versions

-LRB-

an

insist

clause

is

useless

if

it

is

not

succeeded

by

at

least

one

more

version

-RRB-

Moreover

because

at

this

stage

backtracking

is

no

more

possible

the

whole

expansion

result

of

the

original

expansion

source

becomes

a

failure

Note

that

there

is

at

most

one

macro-specioc

test

per

macro

deonition

and

at

most

one

version-specioc

test

per

version

but

there

may

be

arbitrarily

many

assertions

and

insists

in

the

version

sequence

of

a

macro

deonition

Still

there

is

an

important

property

that

all

the

four

clause

types

have

in

common

a

missing

-LRB-

macro-specioc

or

version-specioc

-RRB-

test

can

be

considered

as

a

satisoed

one

and

missing

assertions

and

insists

could

trivially

be

replaced

with

ones

that

are

guaranteed

to

be

always

satisoed

Macro

temporaries

The

set

of

macro

variables

may

include

macro

temporaries

in

addition

to

macro

parameters

Similarly

to

the

macro

parameters

the

macro

temporaries

are

divided

into

data

temporaries

and

label

temporaries

Data

and

label

temporaries

are

valid

as

cell

and

label

references

respectively

but

invalid

as

virtual

form

arguments

-LRB-

see

also

Section

-RRB-

A

data

temporary

is

introduced

in

a

temporary

declaration

-LRB-

USE

-RRB-

and

a

label

temporary

is

introduced

by

including

it

as

a

preox

in

some

statement

The

temporaries

must

be

different

from

the

parameters

and

unique

up

to

the

particular

macro

version

The

macro

writer

must

select

the

storage

class

for

each

data

temporary

When

the

macro

expander

links

an

appropriate

realization

to

a

macro

call

it

binds

each

data

temporary

permanently

to

some

oxed

cell

of

the

user-selected

class

Data

temporaries

can

not

be

made

static

of

them

can

retain

its

contents

between

dioeerent

execution

times

of

the

expansion

result

Data

temporaries

may

be

either

macro-specioc

or

version-specioc

while

label

temporaries

are

always

version-specioc

The

only

purpose

of

introducing

macro-specioc

data

temporaries

is

making

the

macro

deonition

shorter

and

thus

more

easily

readable

Examples

of

both

macro-specioc

and

versionspecioc

temporaries

can

be

found

in

Figure

-LRB-

x

y

-RRB-

-LCB-

TEST

-LRB-

x

y

-RRB-

USE

A

-LSB-

a

-RSB-

M

-LSB-

-RSB-

TEST

R

-LRB-

x

-RRB-

USE

R

-LSB-

-RSB-

-LCB-

-LRB-

x

-RRB-

-LRB-

y

-RRB-

-RCB-

USE

M

-LSB-

-RSB-

-LCB-

BRANCH

-LRB-

x

a

-RRB-

-LSB-

-RSB-

-LRB-

-RRB-

-LRB-

a

y

-RRB-

-RCB-

-RCB-

Figure

Declaration

of

macro

temporaries

In

the

example

in

Figure

temporary

is

specioc

to

version

Temporaries

a

and

are

macro-specioc

ones

from

storage

classes

A

M

and

M

respectively

Version

has

a

version-specioc

temporary

of

class

R

and

version

happens

to

have

a

temporary

with

the

same

name

of

class

M

There

remains

one

important

temporary-related

feature

whose

use

may

sometimes

signiocantly

shorten

the

text

of

a

macro

deonition

The

storage

class

for

each

temporary

has

to

be

selected

by

the

macro

writer

but

this

selection

can

actually

be

delayed

until

expansion

time

Consider

the

deonition

of

the

macro

shown

in

Figure

the

macro

is

a

generalization

of

the

macro

introduced

in

Figure

on

page

-LRB-

x

y

y

x

-RRB-

-LCB-

body

USE

A

And

-LRB-

M

-LRB-

x

y

-RRB-

Lt

-LRB-

R

-LRB-

-RRB-

-RRB-

-RRB-

A

And

-LRB-

R

-LRB-

x

y

-RRB-

Lt

-LRB-

R

-LRB-

-RRB-

-RRB-

-RRB-

R

-LSB-

t

-RSB-

-LCB-

-LRB-

x

t

-RRB-

-LRB-

y

x

-RRB-

-LRB-

t

y

-RRB-

-RCB-

-RCB-

Figure

Delayed

data

temporary

classiocation

Even

the

restricted

needed

two

separate

versions?why

is

a

single

version

now

enough

for

The

answer

is

that

the

version-specioc

temporary

t

of

is

not

classioed

before

expansion

time

If

both

the

arguments

are

from

class

M

and

there

is

at

most

one

cell

from

class

R

free

or

if

both

the

arguments

are

from

class

R

and

there

is

no

additional

cell

from

class

R

free

t

is

taken

from

class

A

otherwise

it

is

taken

from

class

R

If

the

macro

writer

wishes

to

specify

several

alternative

storage

classes

for

a

temporary

as

with

t

of

all

of

them

but

the

last

one

-LRB-

i.e.

the

one

with

the

lowest

priority

-RRB-

must

be

provided

with

an

adjunct

clause

In

general

an

adjunct

clause

as

well

as

a

clause

consists

of

an

integer

designator

that

is

evaluated

at

expansion

time

if

the

evaluation

result

is

nonzero

ReFlEx

takes

the

action

with

which

the

adjunct

clause

is

associated

In

fact

the

use

of

adjunct

clauses

dioeers

from

the

use

of

the

proper

clauses

only

syntactically

the

adjunct

clauses

are

embedded

in

larger

declarations

-LRB-

See

Section

for

another

context

that

embraces

adjunct

clauses

-RRB-

Initialization

of

data

variables

Usually

a

statement

consists

of

a

macro

call

However

a

statement

may

alternatively

consist

of

a

call

of

the

INIT

pseudomacro

-LRB-

there

are

no

other

types

of

pseudomacros

-RRB-

The

use

of

this

pseudomacro

is

closely

related

to

two

constraints

on

version

body

structure

which

aim

to

catch

some

mistakes

possibly

made

by

the

macro

writer

ffl

No

data

temporary

or

output

parameter

can

be

read

before

it

is

written

or

initialized

ffl

Each

output

parameter

must

be

written

or

initialized

-LRB-

neither

this

nor

the

preceding

constraint

concerns

input-output

parameters

-RRB-

INIT

is

directive-like

and

never

produces

any

machine

instructions

It

requires

one

virtual

output

argument

which

should

be

the

data

variable

to

be

initialized

By

such

an

initialization

the

macro

writer

indicates

that

the

current

contents

of

the

cell

represented

by

the

data

variable

are

fully

insigniocant

from

the

viewpoint

of

the

present

macro

deonition

-LRB-

Still

ReFlEx

carefully

protects

the

contents

if

they

are

signiocant

to

some

upper-level

macro

of

the

expansion-time

environment

-RRB-

The

macro

deonition

in

Figure

contains

a

version

employing

INIT

The

whole

macro

deonition

appeared

-LRB-

in

a

slightly

dioeerent

guise

-RRB-

already

in

Figure

on

page

-LRB-

see

Figure

on

page

for

the

deonition

of

the

empty

macro

the

version-specioc

test

of

the

same

version

is

actually

redundant

-RRB-

It

implements

a

general

data

transfer

from

an

arbitrary

source

to

an

arbitrary

destination

-LRB-

s

d

-RRB-

-LCB-

same

TEST

-LRB-

s

d

-RRB-

-LCB-

-LRB-

s

d

-RRB-

-RCB-

-LCB-

set

-LRB-

s

d

-RRB-

-RCB-

INSIST

Not

-LRB-

And

-LRB-

Const

-LRB-

s

-RRB-

R

-LRB-

d

-RRB-

-RRB-

-RRB-

-LCB-

load

-LRB-

s

d

-RRB-

-RCB-

-LCB-

store

-LRB-

s

d

-RRB-

-RCB-

-LCB-

move

-LRB-

s

d

-RRB-

-RCB-

TEST

Equal

-LRB-

s

-RRB-

USE

R

-LSB-

r

-RSB-

-LCB-

INIT

-LRB-

r

-RRB-

move

-LRB-

r

d

-RRB-

sub

-LRB-

d

r

d

-RRB-

-RCB-

USE

R

-LSB-

r

-RSB-

-LCB-

-LRB-

s

r

-RRB-

-LRB-

r

d

-RRB-

-RCB-

-RCB-

Figure

The

macro

The

version

of

is

used

for

resetting

the

accumulator

to

zero

The

version

uses

an

auxiliary

register

whose

arbitrary

contents

are

orst

copied

into

and

then

subtracted

from

the

accumulator

Because

this

register

is

thus

not

overwritten

can

be

used

even

when

there

are

no

free

auxiliary

registers

However

the

fact

that

the

original

value

of

the

register

is

insigniocant

must

be

explicitly

indicated

with

an

INIT

call

Safety

declarations

A

safety

declaration

is

a

macro-specioc

promise

by

the

author

of

the

macro

deonition

saying

that

some

output

is

left

unwritten

ReFlEx

can

orst

utilize

and

later

verify

this

promise

One

might

regard

safety

declarations

as

a

secondary

and

perhaps

the

most

complicated

feature

of

the

ReFlEx

macro

deonition

language

On

the

other

hand

their

use

often

shortens

macro

deonitions

and

is

itself

fairly

safe

The

safety

declaration

provides

the

particular

output

-LRB-

or

input-output

-RRB-

parameter

with

an

adjunct

clause

-LRB-

see

the

end

of

Section

-RRB-

specifying

the

conditions

of

the

promise

However

there

is

an

essential

restriction

in

such

an

adjunct

clause

context-sensitive

forms

=-LRB-

-RRB-

-LRB-

-RRB-

and

-LRB-

-RRB-

can

not

be

even

indirectly

referred

to

This

is

because

ReFlEx

evaluates

the

conditions

already

before

the

intraclass

cell

allocation

in

contrast

the

evaluation

result

of

say

-LRB-

-RRB-

does

not

depend

on

the

intraclass

allocation

The

rest

of

this

subsection

deals

with

a

simple

but

fundamental

example

The

macro

in

Figure

contains

a

safety

declaration

-LRB-

SAFE

-RRB-

This

empty

macro

unconditionally

promises

not

to

write

its

input-output

parameter

this

promise

is

clearly

fulolled

by

the

single

version

of

the

macro

-LRB-

The

motivation

behind

this

macro

deonition

will

soon

become

obvious

-RRB-

-LRB-

x

x

-RRB-

-LCB-

SAFE

x

-LCB-

-RCB-

-RCB-

Figure

Macro

with

a

safety

declaration

Then

the

macro

in

Figure

both

calls

and

includes

a

safety

declaration

of

its

own

Provided

that

s

and

d

represent

cells

belonging

to

the

same

storage

class

promises

not

to

write

output

parameter

d

-LRB-

but

at

the

same

time

requires

that

the

two

parameters

are

mapped

to

a

single

common

cell

-RRB-

By

combining

the

information

from

the

macro-specioc

test

and

the

version

deonition

you

notice

that

calls

can

indeed

be

successful

even

under

this

promise

-LRB-

because

the

call

is

known

not

to

write

d

-RRB-

-LRB-

s

d

-RRB-

-LCB-

SAFE

d

-LRB-

s

d

-RRB-

TEST

Or

-LRB-

-LRB-

s

d

-RRB-

Not

-LRB-

-LRB-

s

d

-RRB-

-RRB-

-RRB-

-LCB-

-LRB-

s

d

-RRB-

-RCB-

move

-LCB-

-LRB-

s

d

-RRB-

-RCB-

-RCB-

Figure

Macro

that

calls

Next

the

macro

in

Figure

is

a

multiplier-by-two

The

call

of

in

the

macro

deonition

saves

us

from

one

additional

version

as

it

is

the

default

version

works

one

regardless

of

whether

input

parameter

x

represents

a

cell

of

class

R

or

M.

-LRB-

x

y

-RRB-

-LCB-

USE

R

-LSB-

r

-RSB-

A

-LSB-

a

-RSB-

const

TEST

Const

-LRB-

x

-RRB-

-LCB-

-LRB-

Add

-LRB-

x

x

-RRB-

y

-RRB-

-RCB-

acc

TEST

A

-LRB-

x

-RRB-

-LCB-

-LRB-

x

r

-RRB-

add

-LRB-

x

r

x

-RRB-

-LRB-

x

y

-RRB-

-RCB-

default

-LCB-

-LRB-

x

r

-RRB-

-LRB-

r

a

-RRB-

add

-LRB-

a

r

a

-RRB-

-LRB-

a

y

-RRB-

-RCB-

-RCB-

Figure

Macro

that

calls

Finally

ReFlEx

expands

a

sample

call

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

in

the

manner

shown

in

Figure

Note

that

ReFlEx

has

accepted

the

default

version

of

and

moreover

mapped

temporary

r

to

cell

R

-LSB-

-RSB-

which

is

the

optimum

one?although

the

call

writes

r

and

R

-LSB-

-RSB-

is

the

only

cell

of

class

R

that

is

not

free

Without

the

safety

declaration

of

this

optimum

mapping

could

not

have

been

found

-LRB-

though

even

then

the

macro-specioc

test

of

would

have

been

suOEcient

for

rejecting

the

non-optimum

mappings

-RRB-

Form

calls

in

macro

deonitions

Unlike

macro

parameters

macro

temporaries

can

not

be

used

as

virtual

form

arguments

The

only

allowed

virtual

form

arguments

inside

a

macro

deonition

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

-LRB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

-LRB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

-RCB-

-RCB-

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

move

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-RCB-

add

-LRB-

A

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LRB-

A

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

-LRB-

A

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

-RCB-

-RCB-

-RCB-

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-LCB-

move

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

add

-LRB-

A

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

R

-LSB-

-RSB-

R

-LSB-

-RSB-

-RCB-

-RCB-

Figure

The

expansion

result

of

a

call

are

macro

parameters

integer

literals

form

calls

and

the

two

reserved

words

THIS

and

NEXT

You

should

remember

that

even

if

a

form

call

serves

as

a

virtual

macro

argument

its

value

is

evaluated

as

if

it

constituted

the

macro-specioc

test

of

the

current

macro

deonition

For

instance

in

the

macro

deonition

-LRB-

x

x

-RRB-

-LCB-

impl

-LCB-

-LRB-

x

x

-RRB-

-LRB-

-LRB-

x

-RRB-

-RRB-

-LRB-

x

x

-RRB-

-RCB-

-RCB-

the

-LRB-

x

-RRB-

form

call

is

guaranteed

to

return

even

if

at

the

call

of

the

parameter

x

is

certainly

not

free

The

reason

is

that

because

x

is

included

in

the

output

parameter

list

-LRB-

and

there

is

no

safety

declaration

-RRB-

the

corresponding

argument

is

free

at

each

call

of

Finally

we

repeat

that

the

context-sensitive

forms

-LRB-

-RRB-

-LRB-

-RRB-

and

-LRB-

-RRB-

can

not

be

called

in

safety

declarations

not

even

indirectly

Macro

expansion

procedure

In

this

section

we

give

a

concise

systematic

description

of

the

macro

expansion

procedure

Despite

its

technical

nature

and

its

total

lack

of

examples

the

description

may

help

you

to

understand

the

ReFlEx

operation

as

a

whole

However

you

can

use

ReFlEx

even

without

reading

this

section

The

macro

expansion

begins

from

an

expansion

source

and

produces

an

expansion

result

The

expansion

source

always

consists

of

a

single

macro

call

and

the

expansion

result

is

a

sequence

of

macro

calls

The

macro

expansion

procedure

comprises

two

main

phases

a

linking

phase

and

a

merging

phase

First

during

the

linking

phase

a

tree

structure

is

built

upon

the

source

macro

call

Each

node

of

this

expansion

tree

contains

a

macro

call

the

node

that

contains

the

source

macro

call

is

the

root

The

nodes

of

the

tree

can

be

divided

into

stock

nodes

and

leaf

nodes

To

the

macro

call

of

each

stock

node

a

realization

has

already

been

linked

while

the

macro

calls

of

the

leaf

nodes

have

not

yet

been

provided

with

a

realization

The

realization

of

a

macro

call

is

selected

from

the

versions

of

the

called

macro

The

linking

phase

is

ended

when

there

is

no

more

room

for

further

reonement

that

is

when

each

leaf

of

the

tree

is

either

a

system

macro

call

-LRB-

which

need

not

be

further

reoned

-RRB-

or

such

an

application

macro

call

that

can

not

be

successfully

reoned

Second

the

merging

phase

linearizes

the

tree

into

a

macro

call

sequence

by

removing

the

stock

nodes

The

merging

phase

is

fairly

trivial

Its

details

are

brieAEy

addressed

onally

in

Section

The

rest

of

this

Section

deals

with

the

linking

phase

Overall

linking

strategy

The

linking

phase

comprises

a

number

of

successive

steps

each

step

links

a

realization

to

an

application

macro

call

which

thus

changes

from

a

leaf

node

into

a

stock

node

How

should

the

leaf

node

to

be

processed

next

be

selected

The

answer

is

that

this

selection

is

fully

insigniocant

as

explained

in

Section

Suppose

that

we

have

somehow

selected

a

leaf

node

Then

a

suitable

realization

version

for

its

macro

call

must

be

selected

from

the

versions

of

the

particular

macro

ReFlEx

traverses

the

versions

in

the

order

specioed

by

the

macro

writer

The

criteria

according

to

which

each

one

of

the

alternative

versions

is

either

accepted

or

rejected

are

cumulatively

formulated

in

Sections

In

particular

the

notion

of

a

free

cell

is

crystallized

in

Section

It

is

possible

that

the

constructed

expansion

tree

contains

an

application

macro

call

leaf

for

which

no

suitable

macro

version

exists

This

means

that

the

whole

task

originally

given

to

ReFlEx

i.e.

the

expansion

of

the

expansion

source

has

irreversibly

failed

ReFlEx

does

not

support

backtracking

The

linking

phase

is

guaranteed

to

end

since

inonite

recursion

is

disabled

the

user

must

set

a

limit

on

the

number

of

nodes

in

the

expansion

tree

-LRB-

and

correspondingly

on

the

allowed

form

call

recursion

depth

-RRB-

Preliminary

deonitions

We

aim

at

generality

and

brevity

in

our

discussion

in

particular

we

want

that

some

crucial

notions

apply

to

both

macro

deonitions

and

expansion

trees

We

begin

with

some

simple

generalizing

conventions

ffl

Cells

and

data

variables

are

collectively

called

markers

ffl

We

assume

that

ReFlEx

quietly

associates

a

unique

implicit

label

temporary

with

each

such

statement

in

a

macro

version

body

that

the

user

has

not

explicitly

provided

with

a

label

temporary

ffl

The

macro

head

is

a

syntactically

valid

macro

call

since

we

want

to

be

able

to

treat

it

as

a

statement

we

assume

that

ReFlEx

provides

even

it

with

an

implicit

label

temporary

Because

of

the

implicit

label

temporaries

no

macro

version

body

can

contain

two

identical

statements

Next

we

give

our

main

umbrella

deonition

ffl

A

macro

scope

or

more

shortly

a

scope

consists

of

a

scope

head

which

is

a

statement

and

a

scope

body

which

is

a

sequence

of

statements

Intuitively

the

scope

body

is

an

implementation

of

the

scope

head

We

introduce

two

scope

types

deonition

scopes

and

expansion

scopes

ffl

For

a

macro

deonition

there

are

as

many

deonition

scopes

as

there

are

macro

versions

The

head

of

each

deonition

scope

is

the

macro

head

statement

and

the

scope

body

is

the

body

of

one

of

the

macro

versions

ffl

For

an

expansion

tree

there

are

as

many

expansion

scopes

as

there

are

stock

nodes

The

head

of

each

expansion

scope

is

the

macro

call

statement

of

the

stock

node

and

the

scope

body

is

the

realization

of

that

macro

call

Thus

any

stock

node

statement

other

than

the

root

statement

both

is

a

head

of

an

expansion

scope

and

belongs

to

the

body

of

another

expansion

scope

We

also

introduce

some

notions

related

to

execution-time

control

propagation

First

concerning

intrascope

control

propagation

we

adopt

the

following

terminology

ffl

Each

statement

in

a

scope

body

has

a

set

of

immediate

successor

statements

associated

with

it

For

instance

a

two-way

branch

typically

has

two

immediate

successors

ffl

A

path

in

a

scope

body

is

a

chain

of

statements

that

is

glued

together

by

the

immediate

successorship

Second

concerning

interscope

control

propagation

we

adopt

two

more

terms

ffl

Each

scope

body

has

exactly

one

entry

point

which

is

the

orst

statement

in

the

scope

body

i.e.

the

statement

that

receives

the

control

from

the

outside

ffl

Each

scope

body

has

a

set

of

exit

points

any

statement

in

the

scope

body

that

may

relinquish

the

control

outside

the

scope

is

an

exit

point

-LRB-

The

last

statement

in

the

scope

body

is

an

exit

point

unless

the

deviation

qualioer

of

its

macro

call

is

JUMP

or

SLEEP

additionally

any

statement

whose

macro

call

has

a

label

argument

in

common

with

the

scope

head

is

an

exit

point

-RRB-

Free

cell

analysis

In

this

subsection

we

formulate

a

precise

deonition

for

the

notion

of

a

free

marker

that

is

a

free

cell

or

a

free

data

variable

We

begin

by

making

three

fairly

intuitive

conventions

explicit

ffl

Each

macro

call

reads

its

input

arguments

ffl

Each

macro

call

writes

its

output

arguments

ffl

Each

INIT

pseudomacro

call

initializes

its

output

argument

We

also

say

that

a

statement

reads

writes

or

initializes

a

marker

if

the

macro

or

pseudomacro

call

of

the

statement

reads

writes

or

initializes

respectively

the

marker

Now

we

are

ready

to

deone

life

paths

which

indicate

data

dependencies

that

span

over

statements

in

the

code

A

path

is

a

life

path

of

a

marker

if

all

the

following

conditions

are

met

ffl

No

statement

in

the

path

writes

or

initializes

the

marker

ffl

The

orst

statement

of

the

path

meets

at

least

one

of

the

following

subconditions

It

reads

the

marker

It

is

an

immediate

successor

of

some

statement

that

writes

the

marker

It

is

an

entry

point

of

the

scope

body

and

the

scope

head

reads

the

marker

ffl

The

last

statement

of

the

path

meets

at

least

one

of

the

following

subconditions

It

has

an

immediate

successor

that

reads

the

marker

It

is

an

exit

point

of

the

scope

body

and

the

scope

head

writes

the

marker

Finally

we

are

able

to

deone

the

set

of

free

markers

for

each

statement

in

any

scope

Below

you

may

choose

to

neglect

the

bracketed

references

to

safeguarding

which

are

relevant

only

when

the

macro

deonitions

contain

safety

declarations

the

notion

of

safeguarding

is

explained

in

Section

We

start

with

the

simple

case

of

deonition

scopes

Every

data

variable

is

free

at

the

deonition

scope

head

-LRB-

this

part

is

included

only

for

the

sake

of

completeness

-RRB-

A

data

variable

is

free

at

a

statement

in

a

deonition

scope

body

if

the

statement

belongs

to

no

life

path

of

the

data

variable

The

case

of

expansion

scopes

is

more

complicated

We

assume

that

the

user

explicitly

provides

the

expansion

source

with

a

disposal

set

which

lists

the

cells

that

can

be

used

as

an

auxiliary

storage

The

deonition

is

recursive

A

cell

is

free

at

the

root

statement

of

an

expansion

tree

if

the

cell

-LSB-

is

not

safeguarded

by

the

root

statement

and

-RSB-

either

belongs

to

the

disposal

set

or

is

written

by

the

root

statement

A

cell

is

free

at

a

statement

in

an

expansion

scope

body

if

both

the

following

subconditions

are

met

ffl

-LSB-

The

cell

is

not

safeguarded

by

the

statement

and

-RSB-

the

statement

belongs

to

no

life

path

of

the

cell

ffl

The

cell

is

free

at

the

expansion

scope

head

Note

in

particular

that

the

freedom

in

expansion

scopes

depends

only

on

the

structure

of

the

current

scope

and

the

enclosing

upper-level

scopes

and

on

the

disposal

set

Eoeectively

this

means

that

the

order

in

which

the

appropriate

realizations

are

linked

to

the

leaves

of

the

expansion

tree

is

indeed

insignificant

as

we

claimed

already

in

Section

-LRB-

It

does

not

matter

whether

safeguarding

is

taken

into

consideration

or

not

-RRB-

Often

when

there

is

no

room

for

misunderstanding

we

simply

say

that

a

cell

or

a

data

variable

is

free

at

some

macro

call

and

actually

mean

freedom

at

the

statement

that

contains

the

macro

call

Variable

binding

When

a

macro

version

body

is

about

to

be

linked

to

a

leaf

macro

call

each

macro

variable

is

mapped

to

a

single

integer

cell

or

label

This

variable

binding

must

respect

a

number

of

constraints

For

instance

the

parameter

lists

of

the

macro

deonition

establish

certain

requirements

on

the

corresponding

argument

lists

of

the

leaf

macro

call

We

specify

now

all

the

constraints

on

variable

binding

-LRB-

again

you

may

choose

to

neglect

the

references

to

safeguarding

-RRB-

Each

data

parameter

must

be

bound

to

the

cell

or

integer

that

is

the

corresponding

argument

of

the

leaf

macro

call

No

input

parameter

that

is

written

by

some

macro

call

in

the

version

body

can

be

bound

to

an

integer

Each

label

parameter

must

be

bound

to

the

label

that

is

the

corresponding

argument

of

the

leaf

macro

call

Each

data

temporary

must

be

bound

to

a

cell

of

the

indicated

storage

class

Each

data

variable

that

is

written

-LSB-

without

safeguarding

-RSB-

by

some

macro

call

in

the

version

body

must

be

bound

to

a

cell

that

is

free

at

the

leaf

macro

call

If

two

distinct

data

variables

are

bound

to

a

single

common

cell

and

if

one

of

them

is

written

by

some

macro

call

in

the

version

body

then

the

other

one

must

not

be

written

by

that

macro

call

If

two

distinct

data

variables

are

bound

to

a

single

common

cell

and

if

one

of

them

is

written

-LSB-

without

safeguarding

-RSB-

by

some

macro

call

in

the

version

body

then

the

other

one

must

be

free

at

that

macro

call

There

may

be

several

successful

but

still

essentially

dioeerent

data

temporary

bindings

available

in

contrast

the

label

temporaries

can

trivially

be

bound

to

unique

labels

that

do

not

previously

occur

in

the

expansion

tree

We

intentionally

leave

it

unspecioed

how

ReFlEx

chooses

among

alternative

successful

data

temporary

bindings

Still

a

wrong

choice

may

later

prove

to

be

a

fatal

mistake

the

whole

expansion

may

result

in

a

failure

that

could

have

been

prevented

by

a

better

choice

If

ReFlEx

onds

a

successful

variable

binding

variable

replacement

can

take

place

in

the

version

body

each

occurrence

of

each

variable

is

replaced

with

an

occurrence

of

the

integer

cell

or

label

to

which

the

particular

variable

is

bound

In

addition

to

the

variable

replacement

some

further

modiocation

in

the

macro

version

body

must

be

simultaneously

carried

out

ffl

Each

INIT

pseudomacro

call

statement

is

removed

if

it

initializes

such

a

variable

that

is

either

bound

to

an

integer

or

bound

to

the

same

cell

as

some

other

variable

that

is

not

free

at

that

INIT

call

Accepting

or

rejecting

a

macro

version

The

expansion

tree

is

not

complete

as

long

as

there

are

leaves

consisting

of

application

macro

calls

For

each

such

leaf

the

versions

of

the

appropriate

macro

deonition

are

traversed

until

an

acceptable

version

is

found

Once

the

version

selection

is

made

it

can

not

ever

be

canceled

not

even

in

the

case

that

a

blind

alley

is

later

met

In

other

words

ReFlEx

does

not

support

backtracking

in

version

selection

Therefore

the

ordering

of

the

macro

versions

and

the

content

of

their

version-specioc

tests

should

be

orchestrated

very

carefully

Each

macro

version

is

accepted

or

rejected

according

to

the

following

criteria

The

version-specioc

test

must

be

successful

A

successful

variable

binding

must

be

found

-LRB-

see

Section

for

the

details

-RRB-

The

macro-specioc

test

of

each

macro

call

in

the

version

body

must

be

successful

-LRB-

To

evaluate

these

tests

ReFlEx

has

to

create

a

provisional

link

between

the

leaf

node

and

an

appropriately

modioed

copy

of

the

version

body

-RRB-

An

implicit

supplement

to

each

macro-specioc

test

is

the

requirement

that

if

two

elements

of

the

macro

parameter

lists

are

identical

then

the

two

corresponding

-LRB-

now

provisionally

oxed

-RRB-

macro

arguments

must

also

be

identical

If

a

particular

macro

version

is

accepted

an

appropriately

modioed

copy

of

the

version

body

is

linked

to

the

leaf

node

and

thus

irreversibly

attached

to

the

expansion

tree

Because

of

the

new

link

the

leaf

node

becomes

a

stock

node

and

the

number

of

expansion

scopes

in

the

tree

is

incremented

by

one

Note

that

we

have

not

yet

specioed

the

time

at

which

the

root

macro

call

has

to

undergo

its

macro-specioc

test

Now

we

straighten

out

even

this

defect

the

whole

linking

phase

begins

with

the

evaluation

of

this

test

Safeguarding

Above

we

have

mentioned

safeguarding

A

macro

call

may

safeguard

only

its

own

output

arguments

More

precisely

we

specify

the

meaning

of

the

term

as

follows

-LRB-

for

safety

declarations

see

Section

-RRB-

ffl

In

an

expansion

tree

a

macro

call

statement

safeguards

a

cell

written

by

it

if

the

macro

deonition

contains

a

safety

declaration

that

provides

the

corresponding

output

-LRB-

or

input-output

-RRB-

parameter

with

an

adjunct

clause

that

is

satisoed

at

that

macro

call

statement

Clearly

the

above

formulation

concerns

only

expansion

trees

however

in

Section

we

spoke

of

safeguarding

even

in

deonition

scope

bodies

We

give

an

intuitive

explanation

what

we

meant

is

such

an

expansion

tree

that

could

be

constituted

by

linking

the

particular

macro

version

body

to

the

leaf

node

in

question

according

to

any

such

variable

binding

that

meets

the

orst

four

of

the

seven

constraints

listed

in

Section

Because

the

most

powerful

ones

of

the

context-sensitive

primitive

forms

can

not

be

employed

in

a

safety

declaration

the

adjunct

clauses

in

the

declaration

may

be

accurately

evaluated

even

against

such

premature

information

about

the

expansion-time

environment

The

reason

for

this

look-ahead

is

rather

obvious

if

an

instance

of

safeguarding

is

detected

in

the

version

body

the

consequences

of

the

remaining

constraints

-LRB-

speciocally

and

-RRB-

may

well

become

less

restrictive

Merging

phase

The

merging

phase

linearizes

the

expansion

tree

into

an

expansion

result

which

is

a

sequence

of

macro

calls

This

linearization

means

that

all

the

following

nodes

are

dropped

ooe

from

the

tree

ffl

All

the

stock

nodes

ffl

Each

remaining

INIT

pseudomacro

call

node

ffl

Each

unreachable

leaf

node

-LRB-

Such

nodes

may

exist

because

macro

deonitions

may

well

include

versions

that

do

not

refer

to

every

label

parameter

-RRB-

Technically

the

expansion

result

does

not

constitute

a

macro

scope

nevertheless

the

macro

calls

in

it

are

provided

with

explicit

free

cell

information

inherited

from

the

expansion

tree

-LRB-

in

which

the

free

cell

information

is

implicit

on

condition

that

safeguarding

is

excluded

-RRB-

Input

and

output

The

input

to

ReFlEx

should

be

a

speciocation

of

the

expansion

source

while

the

output

produced

by

ReFlEx

is

a

listing

of

the

expansion

result

The

expansion

source

is

a

macro

call

and

the

expansion

result

is

a

sequence

of

macro

calls

The

expansion

can

be

considered

as

a

success

if

the

expansion

result

contains

no

application

macro

calls

Optionally

you

can

also

view

the

intermediate

tree

structure

built

by

ReFlEx

during

the

expansion

This

tree

shows

the

links

between

the

individual

macro

calls

and

the

macro

version

bodies

that

are

their

respective

realizations

In

the

examples

below

we

will

consistently

use

the

macro

deoned

in

Figure

on

page

in

Section

Expansion

source

An

expansion

source

line

should

contain

a

macro

call

statement

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

hopeless

Here

ReFlEx

is

required

to

produce

code

that

branches

to

label

if

the

value

in

cell

M

-LSB-

-RSB-

is

zero

Note

that

the

possible

deviation

qualioer

can

not

be

dropped

out

and

the

macro

call

must

be

ended

with

a

semicolon

Note

also

that

a

comment

is

allowed

-LRB-

comments

may

be

useful

especially

when

the

expansion

sources

are

not

given

interactively

but

as

a

batch

-RRB-

Our

next

slightly

extended

example

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

A

-RCB-

permits

ReFlEx

to

use

accumulator

A

as

a

temporary

data

storage

the

disposal

set

is

seen

to

consist

of

cell

A

-LSB-

-RSB-

Note

that

because

storage

class

A

has

only

one

member

A

can

stand

for

A

-LSB-

-RSB-

Our

third

example

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

provides

the

source

macro

call

with

label

and

moreover

specioes

label

as

the

follower

label

The

follower

label

is

the

label

associated

with

the

code

location

immediately

following

the

source

macro

call

-LRB-

or

rather

its

expansion

result

-RRB-

Additional

information

of

this

kind

may

be

useful

when

the

follower

label

is

also

a

label

argument

of

the

source

macro

call

-LRB-

as

in

the

example

-RRB-

Finally

our

fourth

and

last

example

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

presents

a

normal

case

that

produces

a

successful

expansion

result

-LRB-

see

Section

-RRB-

-LRB-

Note

that

if

both

the

disposal

set

and

the

follower

label

are

given

then

the

disposal

set

speciocation

must

come

orst

-RRB-

More

generally

the

expansion

source

is

subject

to

following

restrictions

ffl

The

source

statement

must

consist

either

of

an

application

macro

call

or

of

a

system

macro

call

-LRB-

and

thus

not

of

an

INIT

call

-RRB-

ffl

The

input

arguments

must

be

cell

or

integer

literals

Form

calls

are

not

accepted

ffl

The

output

arguments

must

be

distinct

cell

literals

ffl

Any

syntactically

valid

identioer

is

a

potential

label

literal

and

can

thus

be

used

as

a

label

argument

Expansion

result

Here

we

show

the

expansion

results

for

the

examples

presented

in

Section

In

addition

to

the

expansion

result

the

ReFlEx

output

always

includes

a

heading

that

lists

the

source

statement

the

disposal

set

-LRB-

augmented

with

the

cells

written

by

the

source

macro

call

-RRB-

and

the

possible

follower

label

The

orst

example

that

is

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

-RCB-

-LCB-

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-RCB-

is

an

expansion

with

a

failing

result

By

default

the

disposal

set

is

empty

and

thus

ReFlEx

onds

no

free

cells

As

shown

above

such

application

macro

calls

that

can

not

be

provided

with

a

realization

are

preceded

with

a

question

mark

-LRB-

A

system

macro

call

is

treated

similarly

if

it

constitutes

the

expansion

source

but

does

not

satisfy

the

appropriate

macro-specioc

test

-RRB-

The

second

example

with

a

non-empty

disposal

set

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

A

-RCB-

-LCB-

-LRB-

M

-LSB-

-RSB-

A

-RRB-

BRANCH

eq

-LRB-

A

-RRB-

-LSB-

-RSB-

-RCB-

shows

another

failing

expansion

result

In

this

case

the

source

can

be

provided

with

a

realization

but

no

realization

is

found

for

the

lower-level

call

a

free

auxiliary

register

is

still

wanting

The

next

example

is

somewhat

anomalous

Because

here

the

target

of

the

conditional

branch

is

the

follower

label

the

expansion

result

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

-RCB-

-LCB-

-RCB-

is

empty

-LRB-

but

successful

-RRB-

Finally

the

fourth

and

last

example

gives

us

a

non-empty

successful

expansion

result

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-LCB-

load

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

move

-LRB-

R

-LSB-

-RSB-

A

-RRB-

BRANCH

eq

-LRB-

A

-RRB-

-LSB-

-RSB-

-RCB-

Actually

the

expansion

result

contains

also

the

set

of

free

cells

for

each

macro

call

Safe

estimates

for

the

free

cell

sets

can

be

computed

even

from

listings

such

as

the

above

one

but

Section

tells

you

how

to

view

the

very

sets

-LRB-

inherited

from

the

expansion

tree

-RRB-

themselves

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-LCB-

load

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

move

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

BRANCH

eq

-LRB-

A

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

-RCB-

Intermediate

tree

structure

The

intermediate

tree

structure

built

by

ReFlEx

is

often

very

informative

The

expansion

tree

records

the

expansion

history

the

realizations

for

the

macro

calls

that

are

not

present

in

the

expansion

result

any

more

Instructions

for

tracing

it

are

given

in

Sections

and

For

the

onal

expansion

source

example

considered

above

that

is

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

A

R

-LSB-

-RSB-

-RCB-

the

tree

is

as

follows

BRANCH

-LRB-

M

-LSB-

-RSB-

-RRB-

-LSB-

-RSB-

-LCB-

-LRB-

M

-LSB-

-RSB-

A

-RRB-

-LCB-

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-LCB-

load

-LRB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

-RRB-

-RCB-

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-LCB-

move

-LRB-

R

-LSB-

-RSB-

A

-RRB-

-RCB-

-RCB-

BRANCH

eq

-LRB-

A

-RRB-

-LSB-

-RSB-

-RCB-

You

can

easily

spot

the

leaves

because

of

the

trailing

semicolons

Again

you

could

include

the

free

cell

sets

in

the

listing

In

this

case

however

they

are

redundant

that

is

deducible

from

the

listing

above

This

also

holds

for

expansion

trees

in

general?on

condition

that

the

possibly

safety

declarations

of

the

application

macros

are

additionally

known

Running

ReFlEx

Suppose

you

have

successfully

installed

ReFlEx

along

the

guidelines

given

in

Section

This

section

then

tells

you

how

to

run

ReFlEx

A

ReFlEx

session

can

be

outlined

as

follows

After

loading

the

given

rule

ole

containing

macro

deonitions

ReFlEx

prompts

for

the

orst

expansion

source

Once

you

have

typed

it

in

ReFlEx

responds

by

producing

the

expansion

result

and

prompts

again

for

the

next

expansion

source

Invoking

ReFlEx

You

start

ReFlEx

by

giving

the

command

reflex

<rule-ole>

at

the

operating

system

shell

level

ReFlEx

assumes

that

<rule-ole>

is

a

reference

to

the

operating

system

ole

that

should

be

taken

as

the

rule

ole

-LRB-

The

reference

can

not

begin

with

a

minus

sign

-RRB-

Additionally

there

are

several

command-line

options

which

are

described

in

Section

Some

of

the

options

are

useful

especially

when

the

standard

input

or

output

stream

is

redirected

so

that

ReFlEx

reads

the

expansion

sources

from

or

writes

the

expansion

results

into

some

operating

system

ole

When

ReFlEx

has

started

successfully

it

prints

its

own

prompt

Command-line

options

The

rule

ole

must

be

specioed

on

the

ReFlEx

command

line

Additionally

there

are

a

few

possible

command-line

options

Each

option

begins

with

a

minus

sign

and

contains

no

spaces

The

options

are

s

Omits

printing

the

prompt

-LRB-

s

is

for

silent

-RRB-

This

is

useful

if

the

input

stream

is

redirected

from

an

operating

system

ole

e

Inserts

a

copy

of

the

expansion

source

at

the

beginning

of

the

output

-LRB-

e

is

for

echo

-RRB-

This

may

be

useful

in

the

case

of

input

or

output

stream

redirection

t

Outputs

even

the

intermediate

tree

structure

in

addition

to

the

expansion

result

-LRB-

t

is

for

tree

-RRB-

f

Includes

in

the

output

the

set

of

free

cells

for

each

macro

call

-LRB-

f

is

for

free

-RRB-

n

<int>

Sets

a

limit

on

the

total

number

of

recursively

generated

macro

calls

for

each

expansion

source

in

order

to

cut

ooe

inonite

recursion

-LRB-

n

is

for

number

-RRB-

The

default

limit

is

and

this

option

can

be

used

for

enabling

larger

expansion

trees

The

<int>

oeld

can

be

any

unsigned

decimal

number

however

the

limit

is

automatically

increased

to

at

least

d

<int>

Sets

a

limit

on

the

form

call

recursion

depth

in

order

to

cut

ooe

inonite

recursion

-LRB-

d'

is

for

depth

-RRB-

The

default

limit

is

and

this

option

can

be

used

for

enabling

deeper

recursion

The

<int>

oeld

can

be

any

unsigned

decimal

number

however

the

limit

is

automatically

increased

to

at

least

r

<ole>

Enables

you

to

select

interactively

the

expansion

sources

from

an

operating

system

ole

-LRB-

r

is

for

read

-RRB-

Furthermore

you

can

edit

this

ole

with

you

favorite

text

editor

during

a

single

ReFlEx

session

See

Section

for

more

information

w

<ole>

Starts

recording

the

expansion

sources

to

be

processed

into

an

operating

system

ole

-LRB-

w

is

for

write

-RRB-

The

generated

ole

can

be

fed

back

into

ReFlEx

even

during

the

same

interactive

session

by

using

the

r

<ole>

option

These

options

may

also

be

given

interactively

-LRB-

see

Section

-RRB-

You

may

even

issue

several

instances

of

a

single

option

during

a

ReFlEx

session

either

on

the

command

line

or

interactively

On

the

command

line

the

rightmost

instance

is

the

eoeective

one

However

the

s

e

t

and

f

options

are

toggles

for

example

a

second

s

cancels

the

eoeect

of

the

orst

one

Interactive

control

Normally

you

respond

to

the

ReFlEx

prompt

by

typing

an

expansion

source

on

the

input

line

-LRB-

A

-RRB-

-LCB-

R

-LSB-

-RSB-

-RCB-

However

there

are

also

some

possible

control

buttons

available

for

you

To

exit

ReFlEx

type

a

full

stop

To

receive

a

brief

help

message

on

the

expansion

source

syntax

type

a

question

mark

You

can

also

update

any

command-line

option

-LRB-

but

only

one

at

a

time

-RRB-

n

Having

updated

an

option

you

may

wish

to

process

the

previous

expansion

source

again

To

achieve

this

type

an

exclamation

mark

By

using

the

r

<ole>

option

you

may

select

an

operation

system

ole

ReFlEx

assumes

that

this

ole

consists

of

lines

containing

expansion

sources

A

positive

integer

k

such

as

is

a

control

button

that

tells

ReFlEx

to

process

the

kth

expansion

source

from

the

ole

-LRB-

the

expansion

sources

recorded

through

the

w

<ole>

option

are

provided

with

comments

that

explicitly

build

up

the

appropriate

indexing

-RRB-

You

can

freely

edit

the

ole

between

issuing

instances

of

this

control

button

Exceptional

conditions

and

exception

messages

There

are

several

reasons

why

the

expansion

might

break

up

without

producing

even

a

failing

result

We

believe

that

ReFlEx

can

detect

most

of

such

exceptional

conditions

and

provide

you

with

appropriate

error

messages

Still

an

unguarded

run-time

stack

overAEow

for

instance

may

sometimes

arise

-LRB-

see

below

-RRB-

Every

type

of

exception

message

that

may

be

issued

by

ReFlEx

has

a

unique

message

number

see

Section

for

obtaining

more

information

by

means

of

the

message

number

The

exception

messages

are

divided

into

three

categories

ffl

Fatal

errors

cause

ReFlEx

to

terminate

immediately

ffl

Errors

prevent

the

processing

of

the

current

expansion

source

ffl

Warnings

indicate

less

severe

but

still

unsatisfactory

conditions

that

should

be

polished

by

the

user

Below

we

list

some

exceptional

conditions

Errors

in

the

rule

ole

and

in

the

expansion

source

The

possible

syntactical

and

semantical

errors

in

the

rule

ole

are

detected

already

when

ReFlEx

is

started

and

they

cause

a

premature

program

termination

Similarly

syntactical

and

semantical

errors

in

the

expansion

source

are

detected

before

the

actual

expansion

ReFlEx

can

not

recover

from

syntactical

errors

no

more

than

the

orst

syntactical

error

can

be

pointed

to

the

user

Semantical

errors

in

contrast

can

be

recovered

from

Assertion

failure

in

version

selection

When

ReFlEx

is

selecting

a

macro

version

for

some

macro

call

an

assertion

clause

may

be

reached

If

the

assertion

clause

fails

an

error

message

is

produced

and

the

current

expansion

source

is

discarded

See

Section

for

more

information

on

assertion

clauses

Abortion

in

form

call

evaluation

Because

of

the

lazy

evaluation

the

actual

set

of

form

calls

that

have

to

be

evaluated

is

normally

not

fully

predetermined

If

a

call

of

the

Abort

-LRB-

x

y

z

-RRB-

primitive

form

is

ever

encountered

during

the

macro

expansion

an

error

message

containing

the

evaluated

arguments

x

y

and

z

is

produced

and

the

current

expansion

source

is

discarded

Inonite

recursion

In

principle

both

macro

and

form

deonitions

may

suoeer

from

inonite

recursion

In

practice

however

the

recursion

depth

is

always

limited

If

the

limit

is

reached

an

error

message

is

produced

and

the

current

expansion

source

is

discarded

The

recursion

limits

can

be

changed

by

using

the

n

<int>

and

d

<int>

command-line

options

-LRB-

see

Section

-RRB-

Stack

overAEow

If

the

limits

on

recursion

depth

are

too

large

the

software

stack

-LRB-

probably

set

up

by

the

compiler

that

created

the

ReFlEx

executable

-RRB-

may

overAEow

The

overAEow

is

not

detected

by

ReFlEx

and

may

therefore

have

unpredictable

consequences

The

recursion

limits

can

be

changed

by

using

the

n

<int>

and

d

<int>

command-line

options

-LRB-

see

Section

-RRB-

Heap

overAEow

During

its

execution

ReFlEx

may

ask

the

operating

system

for

more

dynamic

memory

for

new

run-time

data

structures

If

no

more

memory

can

then

be

allocated

a

premature

program

termination

takes

place

Bugs

and

internal

errors

Obviously

there

may

be

bugs

in

the

ReFlEx

implementation

It

is

possible

that

some

bugs

are

detected

by

ReFlEx

itself

these

internal

errors

are

understandably

fatal

ones

We

would

greatly

appreciate

any

information

on

bugs

and

internal

errors

you

may

encounter

please

see

Section

Installing

ReFlEx

Any

non-commercial

use

of

ReFlEx

is

free

of

charge

You

may

install

ReFlEx

on

your

local

workstation

The

operating

system

should

support

ASCII

character

code

and

unsegmented

virtual

memory

-LRB-

as

yet

we

have

not

tried

to

port

ReFlEx

to

MS-DOS

-RRB-

The

practical

details

are

referred

to

in

Section

Technical

information

about

ReFlEx

ReFlEx

source

code

is

written

in

the

C++

programming

language

-LSB-

-RSB-

The

original

compiler

was

GNU

g

Other

programming

tools

utilized

were

the

flex

lexical

analyzer

generator

and

the

GNU

bison

parser

generator

-LSB-

-RSB-

The

integer

range

supported

by

ReFlEx

is

Still

the

C++

compiler

must

implement

the

long

integers

as

at

least

entities

as

required

by

the

ANSI

C

deonition

As

mentioned

in

Section

the

semantics

of

the

arithmetic

primitive

forms

is

determined

by

the

C++

compiler

used

for

compiling

the

ReFlEx

source

code

Indeed

ReFlEx

simply

converts

calls

of

these

primitive

forms

into

the

C++

-LRB-

or

equivalently

C

-RRB-

expressions

shown

in

Table

on

page

This

means

for

instance

that

on

dioeerent

platforms

calling

the

Div

form

with

zero

as

the

divider

may

have

dioeerent

consequences

Obtaining

a

copy

of

ReFlEx

ReFlEx

can

be

obtained

through

the

Internet

by

anonymous

ftp

contact

ftp

server

saturn.hut.fi

move

into

directory

pub/reflex

and

look

for

ole

README

Alternatively

if

you

have

a

World

Wide

Web

browser

you

may

directly

view

the

location

ftp

saturn.hut.fi

pub/reflex/README

File

README

specioes

how

you

can

ond

the

following

items

ffl

Description

of

the

possible

changes

made

to

the

ReFlEx

documentation

ffl

ReFlEx

source

code

and

instructions

for

compiling

it

ffl

A

listing

of

ReFlEx

exception

messages

ffl

A

sample

ReFlEx

rule

ole

-LRB-

which

also

constitutes

Appendix

C

-RRB-

and

a

companion

ole

with

sample

expansion

sources

ffl

An

ooe-the-record

exercise

for

prospective

ReFlEx

programmers

-LRB-

see

also

Appendix

C

-RRB-

Finally

we

would

greatly

appreciate

any

comments

questions

bug

reports

and

suggestions

for

improvements

The

README

ole

records

some

convenient

ways

to

contact

us

A

Rule

ole

syntax

In

this

appendix

we

present

a

deonition

for

the

ReFlEx

rule

ole

syntax

You

can

absorb

this

deonition

easily

if

you

are

familiar

with

the

syntax

of

lex

and

yacc

input

oles

-LRB-

These

two

programs

are

widely

used

compiler-generation

tools

lex

is

a

lexical

analyzer

generator

and

yacc

is

a

parser

generator

-LSB-

-RSB-

-RRB-

Token

structure

First

we

present

the

required

token

structure

by

using

a

formalism

that

closely

resembles

the

lex

input

formalism

-LRB-

Consult

-LSB-

-RSB-

if

you

are

not

familiar

with

lex

-RRB-

letter

-LSB-

A-Za-z

-RSB-

digit

-LSB-

-RSB-

id

-LCB-

letter

-RCB-

-LRB-

-LCB-

letter

-RCB-

-LCB-

digit

-RCB-

-RRB-

int

-LCB-

digit

-RCB-

-LCB-

-RCB-

t

-LCB-

-RCB-

n

-LCB-

-RCB-

r

-LCB-

-RCB-

-LCB-

-RCB-

ASSERT

-LCB-

return

-LRB-

ASSERT

-RRB-

-RCB-

BRANCH

-LCB-

return

-LRB-

BRANCH

-RRB-

-RCB-

HEADER

-LCB-

return

-LRB-

HEADER

-RRB-

-RCB-

INIT

-LCB-

return

-LRB-

INIT

-RRB-

-RCB-

INPUT

-LCB-

return

-LRB-

INPUT

-RRB-

-RCB-

INSIST

-LCB-

return

-LRB-

INSIST

-RRB-

-RCB-

JUMP

-LCB-

return

-LRB-

JUMP

-RRB-

-RCB-

NEXT

-LCB-

return

-LRB-

NEXT

-RRB-

-RCB-

SAFE

-LCB-

return

-LRB-

SAFE

-RRB-

-RCB-

SEED

-LCB-

return

-LRB-

SEED

-RRB-

-RCB-

SLEEP

-LCB-

return

-LRB-

SLEEP

-RRB-

-RCB-

STATE

-LCB-

return

-LRB-

STATE

-RRB-

-RCB-

STORAGE

-LCB-

return

-LRB-

STORAGE

-RRB-

-RCB-

SYSTEM

-LCB-

return

-LRB-

SYSTEM

-RRB-

-RCB-

TEST

-LCB-

return

-LRB-

TEST

-RRB-

-RCB-

THIS

-LCB-

return

-LRB-

THIS

-RRB-

-RCB-

USE

-LCB-

return

-LRB-

USE

-RRB-

-RCB-

UTILITY

-LCB-

return

-LRB-

UTILITY

-RRB-

-RCB-

-LCB-

id

-RCB-

-LCB-

return

-LRB-

ID

-RRB-

-RCB-

-LCB-

int

-RCB-

-LCB-

return

-LRB-

INT

-RRB-

-RCB-

-LCB-

return

yytext

-LSB-

-RSB-

-RCB-

Overall

structure

Second

we

present

the

overall

hierarchical

structure

of

the

rule

ole

by

using

a

context-free

grammar

formalism

Some

of

the

terminal

symbols

-LRB-

i.e.

the

uppercase

ones

-RRB-

of

the

grammar

appeared

already

in

the

token

structure

deonition

above

rulebase

header

storage

system

utility

header

HEADER

-LCB-

-RCB-

form

form

ID

-LRB-

-RRB-

const

ID

-LCB-

fseed

fstate

-RCB-

item

item

STATE

INPUT

THIS

NEXT

ID

ID

ID

fseed

SEED

const

fstate

STATE

const

fother

fother

ID

const

storage

STORAGE

-LCB-

-RCB-

class

class

ID

-LSB-

const

-RSB-

system

SYSTEM

-LCB-

-RCB-

instr

utility

UTILITY

-LCB-

-RCB-

macrodef

stmt

instr

ihead

-LCB-

test

-RCB-

macrodef

ihead

-LCB-

save

test

local

-RCB-

stmt

ID

shead

shead

ihead

ID

-LRB-

inlist

outlist

-RRB-

dstlist

dev

ID

-LRB-

inlist

outlist

-RRB-

dstlist

shead

ID

-LRB-

clist

outlist

-RRB-

dstlist

dev

ID

-LRB-

clist

outlist

-RRB-

dstlist

INIT

-LRB-

ID

-RRB-

dev

JUMP

BRANCH

SLEEP

inlist

clist

outlist

dstlist

-LSB-

-RSB-

save

SAFE

savedecl

savedecl

savedecl

ID

const

test

TEST

const

local

USE

tempdecl

tempdecl

tempdecl

ID

const

tempdecl

ID

-LSB-

-RSB-

const

const

const

ID

-LRB-

-RRB-

item

integer

dsym

classid

-LRB-

-RRB-

-LRB-

-RRB-

integer

integer

integer

INT

classid

ID

dsym

choice

choice

ASSERT

const

INSIST

const

ID

test

local

-LCB-

-RCB-

B

Expansion

source

syntax

In

this

appendix

we

present

a

syntax

deonition

for

a

ReFlEx

expansion

source

which

is

to

be

typed

on

the

input

line

as

a

response

to

the

ReFlEx

prompt

You

can

absorb

this

deonition

easily

if

you

are

familiar

with

the

syntax

of

lex

and

yacc

input

oles

-LRB-

These

two

programs

are

widely

used

compiler-generation

tools

lex

is

a

lexical

analyzer

generator

and

yacc

is

a

parser

generator

-LSB-

-RSB-

-RRB-

Token

structure

First

we

present

the

required

token

structure

by

using

a

formalism

that

closely

resembles

the

lex

input

formalism

-LRB-

Consult

-LSB-

-RSB-

if

you

are

not

familiar

with

lex

-RRB-

letter

-LSB-

A-Za-z

-RSB-

digit

-LSB-

-RSB-

id

-LCB-

letter

-RCB-

-LRB-

-LCB-

letter

-RCB-

-LCB-

digit

-RCB-

-RRB-

int

-LCB-

digit

-RCB-

-LRB-

-LCB-

digit

-RCB-

-RRB-

-LCB-

-RCB-

t

-LCB-

-RCB-

n

-LCB-

return

-LRB-

-RRB-

-RCB-

r

-LCB-

-RCB-

-LCB-

-RCB-

ASSERT

-LCB-

return

-LRB-

-RRB-

-RCB-

BRANCH

-LCB-

return

-LRB-

BRANCH

-RRB-

-RCB-

HEADER

-LCB-

return

-LRB-

-RRB-

-RCB-

INIT

-LCB-

return

-LRB-

-RRB-

-RCB-

INPUT

-LCB-

return

-LRB-

-RRB-

-RCB-

INSIST

-LCB-

return

-LRB-

-RRB-

-RCB-

JUMP

-LCB-

return

-LRB-

JUMP

-RRB-

-RCB-

NEXT

-LCB-

return

-LRB-

-RRB-

-RCB-

SAFE

-LCB-

return

-LRB-

-RRB-

-RCB-

SEED

-LCB-

return

-LRB-

-RRB-

-RCB-

SLEEP

-LCB-

return

-LRB-

SLEEP

-RRB-

-RCB-

STATE

-LCB-

return

-LRB-

-RRB-

-RCB-

STORAGE

-LCB-

return

-LRB-

-RRB-

-RCB-

SYSTEM

-LCB-

return

-LRB-

-RRB-

-RCB-

TEST

-LCB-

return

-LRB-

-RRB-

-RCB-

THIS

-LCB-

return

-LRB-

-RRB-

-RCB-

USE

-LCB-

return

-LRB-

-RRB-

-RCB-

UTILITY

-LCB-

return

-LRB-

-RRB-

-RCB-

-LCB-

id

-RCB-

-LCB-

return

-LRB-

ID

-RRB-

-RCB-

-LCB-

int

-RCB-

-LCB-

return

-LRB-

INT

-RRB-

-RCB-

-LCB-

return

yytext

-LSB-

-RSB-

-RCB-

Overall

structure

Second

we

present

the

overall

hierarchical

structure

of

the

expansion

source

by

using

a

context-free

grammar

formalism

Some

of

the

terminal

symbols

-LRB-

i.e.

the

uppercase

ones

-RRB-

of

the

grammar

appeared

already

in

the

token

structure

deonition

above

inputline

stmt

free

next

stmt

ID

shead

shead

shead

ID

-LRB-

ilist

outlist

-RRB-

dstlist

dev

ID

-LRB-

ilist

outlist

-RRB-

dstlist

dev

SLEEP

BRANCH

JUMP

ilist

outlist

dstlist

-LSB-

-RSB-

free

-LCB-

-RCB-

next

ID

const

const

const

item

integer

integer

integer

integer

INT

item

item

item

ID

-LSB-

integer

-RSB-

ID

ID

ID

C

A

sample

code

generator

This

appendix

presents

a

self-contained

ReFlEx

rule

ole

It

can

be

seen

as

a

simple

code

generator

for

the

same

simple

hypothetical

processor

architecture

that

is

dealt

with

in

the

examples

in

the

text

-LRB-

See

Section

for

obtaining

an

electronic

copy

of

this

rule

ole

-RRB-

At

this

point

you

might

be

interested

in

trying

to

solve

a

non-trivial

macro

writing

exercise

Therefore

we

ask

you

to

extend

the

rule

ole

as

follows

ffl

Write

a

macro

-LRB-

s

n

d

-RRB-

that

transfers

data

from

an

arbitrary

source

s

into

an

arbitrary

destination

d

and

most

of

all

simultaneously

shifts

the

data

to

the

left

by

n

bit

positions

-LRB-

you

can

require

that

n

represents

a

non-negative

integer?and

not

a

cell

-RRB-

In

other

words

the

macro

should

implement

the

C

language

expression

d

s

n

We

would

be

pleased

to

answer

any

questions

concerning

this

exercise

-LRB-

Again

see

Section

for

a

pointer

to

our

contact

information

-RRB-

A

ReFlEx

rule

file

HEADER

-LCB-

Abort

-LRB-

x

y

z

-RRB-

Abort

-LRB-

x

y

z

-RRB-

If

-LRB-

x

y

z

-RRB-

If

-LRB-

x

y

z

-RRB-

Add

-LRB-

x

y

-RRB-

Add

-LRB-

x

y

-RRB-

BNand

-LRB-

x

y

-RRB-

BNand

-LRB-

x

y

-RRB-

BShl

-LRB-

x

y

-RRB-

BShl

-LRB-

x

y

-RRB-

Div

-LRB-

x

y

-RRB-

If

-LRB-

y

Div

-LRB-

x

y

-RRB-

Abort

-LRB-

x

y

-RRB-

-RRB-

Lt

-LRB-

x

y

-RRB-

Lt

-LRB-

x

y

-RRB-

Mul

-LRB-

x

y

-RRB-

Mul

-LRB-

x

y

-RRB-

Nand

-LRB-

x

y

-RRB-

Nand

-LRB-

x

y

-RRB-

Not

-LRB-

x

-RRB-

Nand

-LRB-

x

x

-RRB-

BNot

-LRB-

x

-RRB-

BNand

-LRB-

x

x

-RRB-

Lte

-LRB-

x

y

-RRB-

Not

-LRB-

Lt

-LRB-

y

x

-RRB-

-RRB-

Gt

-LRB-

x

y

-RRB-

Lt

-LRB-

y

x

-RRB-

Gte

-LRB-

x

y

-RRB-

Lte

-LRB-

y

x

-RRB-

Eq

-LRB-

x

y

-RRB-

And

-LRB-

Gte

-LRB-

x

y

-RRB-

Gte

-LRB-

y

x

-RRB-

-RRB-

Neq

-LRB-

x

y

-RRB-

Not

-LRB-

Eq

-LRB-

x

y

-RRB-

-RRB-

Sub

-LRB-

x

y

-RRB-

Add

-LRB-

x

Add

-LRB-

BNot

-LRB-

y

-RRB-

-RRB-

-RRB-

And

-LCB-

SEED

STATE

If

-LRB-

STATE

INPUT

-RRB-

-RCB-

Or

-LCB-

SEED

STATE

If

-LRB-

STATE

INPUT

-RRB-

-RCB-

Const

-LCB-

SEED

STATE

And

-LRB-

STATE

Not

-LRB-

-LRB-

INPUT

-RRB-

-RRB-

Not

-LRB-

-LRB-

INPUT

-RRB-

-RRB-

-RRB-

-RCB-

Equal

-LCB-

SEED

STATE

If

-LRB-

STATE

If

-LRB-

later

And

-LRB-

Const

-LRB-

INPUT

-RRB-

Eq

-LRB-

value

INPUT

-RRB-

-RRB-

Const

-LRB-

INPUT

-RRB-

-RRB-

-RRB-

later

value

If

-LRB-

later

value

INPUT

-RRB-

-RCB-

Type

-LRB-

x

-RRB-

If

-LRB-

A

-LRB-

x

-RRB-

If

-LRB-

R

-LRB-

x

-RRB-

If

-LRB-

M

-LRB-

x

-RRB-

If

-LRB-

Const

-LRB-

x

-RRB-

-RRB-

-RRB-

-RRB-

-RRB-

Ordered

-LRB-

x

y

-RRB-

If

-LRB-

Const

-LRB-

x

y

-RRB-

Lte

-LRB-

x

y

-RRB-

Lte

-LRB-

Type

-LRB-

x

-RRB-

Type

-LRB-

y

-RRB-

-RRB-

-RRB-

-RCB-

HEADER

STORAGE

-LCB-

M

-LSB-

-RSB-

R

-LSB-

-RSB-

A

-LSB-

-RSB-

-RCB-

SYSTEM

-LCB-

set

-LRB-

c

r

-RRB-

-LCB-

TEST

And

-LRB-

R

-LRB-

r

-RRB-

Const

-LRB-

c

-RRB-

Gte

-LRB-

-RRB-

Lte

-LRB-

c

-RRB-

-RRB-

-RCB-

load

-LRB-

m

r

-RRB-

-LCB-

TEST

And

-LRB-

R

-LRB-

r

-RRB-

M

-LRB-

m

-RRB-

-RRB-

-RCB-

store

-LRB-

r

m

-RRB-

-LCB-

TEST

And

-LRB-

R

-LRB-

r

-RRB-

M

-LRB-

m

-RRB-

-RRB-

-RCB-

move

-LRB-

s

d

-RRB-

-LCB-

TEST

And

-LRB-

Or

-LRB-

A

-LRB-

s

-RRB-

R

-LRB-

s

-RRB-

-RRB-

Or

-LRB-

A

-LRB-

d

-RRB-

R

-LRB-

d

-RRB-

-RRB-

-RRB-

-RCB-

add

-LRB-

a

r

a

-RRB-

-LCB-

TEST

And

-LRB-

A

-LRB-

a

-RRB-

R

-LRB-

r

-RRB-

-RRB-

-RCB-

sub

-LRB-

a

r

a

-RRB-

-LCB-

TEST

And

-LRB-

A

-LRB-

a

-RRB-

R

-LRB-

r

-RRB-

-RRB-

-RCB-

JUMP

goto

-LRB-

-RRB-

-LSB-

l

-RSB-

-LCB-

-RCB-

BRANCH

eq

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-LCB-

TEST

A

-LRB-

a

-RRB-

-RCB-

BRANCH

gt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-LCB-

TEST

A

-LRB-

a

-RRB-

-RCB-

BRANCH

lt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-LCB-

TEST

A

-LRB-

a

-RRB-

-RCB-

-RCB-

UTILITY

-LCB-

-LRB-

x

x

-RRB-

-LCB-

do

not

do

anything

-LCB-

-RCB-

-RCB-

-LRB-

s

d

-RRB-

-LCB-

move

data

from

s

into

d

same

TEST

-LRB-

s

d

-RRB-

-LCB-

-LRB-

s

d

-RRB-

-RCB-

-LCB-

set

-LRB-

s

d

-RRB-

-RCB-

INSIST

Not

-LRB-

And

-LRB-

Const

-LRB-

s

-RRB-

R

-LRB-

d

-RRB-

-RRB-

-RRB-

-LCB-

load

-LRB-

s

d

-RRB-

-RCB-

-LCB-

store

-LRB-

s

d

-RRB-

-RCB-

-LCB-

move

-LRB-

s

d

-RRB-

-RCB-

TEST

Equal

-LRB-

s

-RRB-

USE

R

-LSB-

r

-RSB-

-LCB-

INIT

-LRB-

r

-RRB-

move

-LRB-

r

d

-RRB-

sub

-LRB-

d

r

d

-RRB-

-RCB-

USE

R

-LSB-

r

-RSB-

-LCB-

-LRB-

s

r

-RRB-

-LRB-

r

d

-RRB-

-RCB-

-RCB-

-LRB-

x

x

-RRB-

-LCB-

do

not

do

anything

safeguard

x

SAFE

x

-LCB-

-RCB-

-RCB-

-LRB-

s

d

-RRB-

-LCB-

move

data

from

s

into

d

if

s

and

d

belong

to

a

common

class

they

are

forced

to

be

aliases

of

each

other

SAFE

d

-LRB-

s

d

-RRB-

TEST

Or

-LRB-

-LRB-

s

d

-RRB-

Not

-LRB-

-LRB-

s

d

-RRB-

-RRB-

-RRB-

-LCB-

-LRB-

s

d

-RRB-

-RCB-

move

-LCB-

-LRB-

s

d

-RRB-

-RCB-

-RCB-

-LRB-

x

y

-RRB-

-LCB-

y

is

set

to

the

value

of

x

multiplied

by

USE

R

-LSB-

r

-RSB-

A

-LSB-

a

-RSB-

const

TEST

Const

-LRB-

x

-RRB-

-LCB-

-LRB-

Add

-LRB-

x

x

-RRB-

y

-RRB-

-RCB-

acc

TEST

A

-LRB-

x

-RRB-

-LCB-

-LRB-

x

r

-RRB-

add

-LRB-

x

r

x

-RRB-

-LRB-

x

y

-RRB-

-RCB-

default

-LCB-

-LRB-

x

r

-RRB-

-LRB-

r

a

-RRB-

add

-LRB-

a

r

a

-RRB-

-LRB-

a

y

-RRB-

-RCB-

-RCB-

-LRB-

x

y

y

x

-RRB-

-LCB-

swap

the

contents

of

x

and

y

body

USE

A

And

-LRB-

M

-LRB-

x

y

-RRB-

Lt

-LRB-

R

-LRB-

-RRB-

-RRB-

-RRB-

A

And

-LRB-

R

-LRB-

x

y

-RRB-

Lt

-LRB-

R

-LRB-

-RRB-

-RRB-

-RRB-

R

-LSB-

t

-RSB-

-LCB-

-LRB-

x

t

-RRB-

-LRB-

y

x

-RRB-

-LRB-

t

y

-RRB-

-RCB-

-RCB-

BRANCH

-LRB-

x

-RRB-

-LSB-

l

-RSB-

-LCB-

is

x

zero

next

TEST

-LRB-

l

NEXT

-RRB-

-LCB-

-RCB-

zero

TEST

Equal

-LRB-

x

-RRB-

-LCB-

JUMP

goto

-LRB-

-RRB-

-LSB-

l

-RSB-

-RCB-

const

TEST

Const

-LRB-

x

-RRB-

-LCB-

-RCB-

default

USE

A

-LSB-

a

-RSB-

-LCB-

-LRB-

x

a

-RRB-

BRANCH

eq

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-RCB-

BRANCH

-LRB-

x

-RRB-

-LSB-

l

-RSB-

-LCB-

is

x

positive

next

TEST

-LRB-

l

NEXT

-RRB-

-LCB-

-RCB-

pos

TEST

Gt

-LRB-

x

-RRB-

-LCB-

JUMP

goto

-LRB-

-RRB-

-LSB-

l

-RSB-

-RCB-

const

TEST

Const

-LRB-

x

-RRB-

-LCB-

-RCB-

default

USE

A

-LSB-

a

-RSB-

-LCB-

-LRB-

x

a

-RRB-

BRANCH

gt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-RCB-

BRANCH

-LRB-

x

-RRB-

-LSB-

l

-RSB-

-LCB-

is

x

negative

next

TEST

-LRB-

l

NEXT

-RRB-

-LCB-

-RCB-

neg

TEST

Lt

-LRB-

x

-RRB-

-LCB-

JUMP

goto

-LRB-

-RRB-

-LSB-

l

-RSB-

-RCB-

const

TEST

Const

-LRB-

x

-RRB-

-LCB-

-RCB-

default

USE

A

-LSB-

a

-RSB-

-LCB-

-LRB-

x

a

-RRB-

BRANCH

lt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-RCB-

BRANCH

-LRB-

x

y

-RRB-

-LSB-

l

-RSB-

-LCB-

is

x

greater

than

y

TEST

Or

-LRB-

A

-LRB-

-RRB-

-LRB-

l

NEXT

-RRB-

-LRB-

x

y

-RRB-

Const

-LRB-

x

y

-RRB-

And

-LRB-

A

-LRB-

x

-RRB-

Equal

-LRB-

y

-RRB-

-RRB-

And

-LRB-

A

-LRB-

y

-RRB-

Equal

-LRB-

x

-RRB-

-RRB-

-RRB-

USE

A

-LSB-

a

-RSB-

R

-LSB-

r

-RSB-

swap

TEST

Not

-LRB-

Ordered

-LRB-

x

y

-RRB-

-RRB-

-LCB-

BRANCH

-LRB-

y

x

-RRB-

-LSB-

l

-RSB-

-RCB-

INSIST

Ordered

-LRB-

x

y

-RRB-

next

TEST

-LRB-

l

NEXT

-RRB-

-LCB-

-RCB-

same

TEST

-LRB-

x

y

-RRB-

-LCB-

-RCB-

const

TEST

Const

-LRB-

x

y

-RRB-

-LCB-

-RCB-

TEST

Equal

-LRB-

y

-RRB-

-LCB-

-LRB-

x

a

-RRB-

BRANCH

gt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-LCB-

-LRB-

x

a

-RRB-

-LRB-

y

r

-RRB-

sub

-LRB-

a

r

a

-RRB-

BRANCH

gt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-LCB-

-LRB-

y

a

-RRB-

-LRB-

x

r

-RRB-

sub

-LRB-

a

r

a

-RRB-

BRANCH

lt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-RCB-

BRANCH

-LRB-

x

y

-RRB-

-LSB-

l

-RSB-

-LCB-

is

x

less

than

y

TEST

Or

-LRB-

A

-LRB-

-RRB-

-LRB-

l

NEXT

-RRB-

-LRB-

x

y

-RRB-

Const

-LRB-

x

y

-RRB-

And

-LRB-

A

-LRB-

x

-RRB-

Equal

-LRB-

y

-RRB-

-RRB-

And

-LRB-

A

-LRB-

y

-RRB-

Equal

-LRB-

x

-RRB-

-RRB-

-RRB-

USE

A

-LSB-

a

-RSB-

R

-LSB-

r

-RSB-

swap

TEST

Not

-LRB-

Ordered

-LRB-

x

y

-RRB-

-RRB-

-LCB-

BRANCH

-LRB-

y

x

-RRB-

-LSB-

l

-RSB-

-RCB-

INSIST

Ordered

-LRB-

x

y

-RRB-

next

TEST

-LRB-

l

NEXT

-RRB-

-LCB-

-RCB-

same

TEST

-LRB-

x

y

-RRB-

-LCB-

-RCB-

TEST

Equal

-LRB-

x

y

-RRB-

-LCB-

-RCB-

const

TEST

Const

-LRB-

x

y

-RRB-

-LCB-

JUMP

goto

-LRB-

-RRB-

-LSB-

l

-RSB-

-RCB-

TEST

Equal

-LRB-

y

-RRB-

-LCB-

-LRB-

x

a

-RRB-

BRANCH

lt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-LCB-

-LRB-

x

a

-RRB-

-LRB-

y

r

-RRB-

sub

-LRB-

a

r

a

-RRB-

BRANCH

lt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-LCB-

-LRB-

y

a

-RRB-

-LRB-

x

r

-RRB-

sub

-LRB-

a

r

a

-RRB-

BRANCH

gt

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-RCB-

-LRB-

x

y

z

-RRB-

-LCB-

add

x

to

y

and

put

the

result

into

z

TEST

Or

-LRB-

A

-LRB-

-RRB-

Const

-LRB-

x

y

-RRB-

Equal

-LRB-

y

-RRB-

-LRB-

x

y

-RRB-

-RRB-

USE

A

-LSB-

a

-RSB-

R

-LSB-

r

-RSB-

swap

TEST

Not

-LRB-

Ordered

-LRB-

x

y

-RRB-

-RRB-

-LCB-

-LRB-

y

x

z

-RRB-

-RCB-

INSIST

Ordered

-LRB-

x

y

-RRB-

TEST

Const

-LRB-

x

y

-RRB-

-LCB-

-LRB-

Add

-LRB-

x

y

-RRB-

z

-RRB-

-RCB-

TEST

Equal

-LRB-

y

-RRB-

-LCB-

-LRB-

x

z

-RRB-

-RCB-

same

TEST

-LRB-

x

y

-RRB-

-LCB-

-LRB-

x

z

-RRB-

-RCB-

default

-LCB-

-LRB-

x

a

-RRB-

-LRB-

y

r

-RRB-

add

-LRB-

a

r

a

-RRB-

-LRB-

a

z

-RRB-

-RCB-

-RCB-

-LRB-

x

y

z

-RRB-

-LCB-

subtract

y

from

x

and

put

the

result

into

z

USE

A

-LSB-

a

-RSB-

R

-LSB-

r

-RSB-

TEST

Const

-LRB-

x

y

-RRB-

-LCB-

-LRB-

Sub

-LRB-

x

y

-RRB-

z

-RRB-

-RCB-

same

TEST

-LRB-

x

y

-RRB-

-LCB-

-LRB-

z

-RRB-

-RCB-

TEST

Equal

-LRB-

y

-RRB-

-LCB-

-LRB-

x

z

-RRB-

-RCB-

TEST

And

-LRB-

R

-LRB-

y

-RRB-

Equal

-LRB-

x

-RRB-

-RRB-

-LCB-

-LRB-

y

a

-RRB-

sub

-LRB-

a

y

a

-RRB-

sub

-LRB-

a

y

a

-RRB-

-LRB-

a

z

-RRB-

-RCB-

TEST

And

-LRB-

A

-LRB-

y

-RRB-

Equal

-LRB-

x

-RRB-

-RRB-

-LCB-

-LRB-

y

r

-RRB-

sub

-LRB-

y

r

y

-RRB-

sub

-LRB-

y

r

y

-RRB-

-LRB-

y

z

-RRB-

-RCB-

TEST

And

-LRB-

A

-LRB-

y

-RRB-

R

-LRB-

x

-RRB-

-LRB-

x

-RRB-

Equal

-LRB-

R

-LRB-

-RRB-

-RRB-

-RRB-

-LCB-

sub

-LRB-

y

x

y

-RRB-

-LRB-

y

x

-RRB-

sub

-LRB-

y

x

y

-RRB-

sub

-LRB-

y

x

y

-RRB-

-LRB-

y

z

-RRB-

-RCB-

TEST

And

-LRB-

A

-LRB-

y

-RRB-

Or

-LRB-

M

-LRB-

x

-RRB-

Const

-LRB-

x

-RRB-

-RRB-

Equal

-LRB-

R

-LRB-

-RRB-

-RRB-

-RRB-

-LCB-

-LRB-

x

r

-RRB-

sub

-LRB-

y

r

y

-RRB-

-LRB-

y

r

-RRB-

sub

-LRB-

y

r

y

-RRB-

sub

-LRB-

y

r

y

-RRB-

-LRB-

y

z

-RRB-

-RCB-

-LCB-

-LRB-

x

a

-RRB-

-LRB-

y

r

-RRB-

sub

-LRB-

a

r

a

-RRB-

-LRB-

a

z

-RRB-

-RCB-

-LCB-

-LRB-

y

r

-RRB-

-LRB-

x

a

-RRB-

sub

-LRB-

a

r

a

-RRB-

-LRB-

a

z

-RRB-

-RCB-

-RCB-

BRANCH

-LRB-

x

y

-RRB-

-LSB-

l

-RSB-

-LCB-

are

x

and

y

equal

TEST

Or

-LRB-

A

-LRB-

-RRB-

-LRB-

l

NEXT

-RRB-

Equal

-LRB-

x

y

-RRB-

Const

-LRB-

x

y

-RRB-

-LRB-

x

y

-RRB-

-RRB-

next

TEST

-LRB-

l

NEXT

-RRB-

-LCB-

-RCB-

TEST

Equal

-LRB-

x

y

-RRB-

-LCB-

JUMP

goto

-LRB-

-RRB-

-LSB-

l

-RSB-

-RCB-

TEST

Const

-LRB-

x

y

-RRB-

-LCB-

-RCB-

same

TEST

-LRB-

x

y

-RRB-

-LCB-

JUMP

goto

-LRB-

-RRB-

-LSB-

l

-RSB-

-RCB-

swap

TEST

Not

-LRB-

Ordered

-LRB-

x

y

-RRB-

-RRB-

-LCB-

BRANCH

-LRB-

y

x

-RRB-

-LSB-

l

-RSB-

-RCB-

INSIST

Ordered

-LRB-

x

y

-RRB-

default

USE

A

-LSB-

a

-RSB-

-LCB-

-LRB-

x

y

a

-RRB-

BRANCH

eq

-LRB-

a

-RRB-

-LSB-

l

-RSB-

-RCB-

-RCB-

-RCB-

UTILITY

Acknowledgements

The

author

wishes

to

thank

Professor

Leo

Ojala

for

his

orm

interest

in

the

subject

and

for

the

arrangements

that

have

made

this

work

possible

During

the

implementation

and

documentation

phases

of

the

work

Dr.

Johan

Lilius

and

Dr.

Ilkka

Niemel

have

provided

many

valuable

suggestions

The

onancial

support

from

Helsinki

Graduate

School

in

Computer

Science

and

Engineering

Academy

of

Finland

and

Foundation

of

Technology

is

also

gratefully

acknowledged

References

-LSB-

-RSB-

A.

V.

Aho

R.

Sethi

and

J.

D.

Ullman

Compilers

Principles

Techniques

and

Tools

Addison-Wesley

Reading

-LRB-

Massachusetts

USA

-RRB-

-LSB-

-RSB-

G.

Araujo

S.

Devadas

K.

Keutzer

S.

Liao

S.

Malik

A.

Sundarsanam

S.

Tjiang

and

A.

Wang

Challenges

in

code

generation

for

embedded

processors

In

-LSB-

-RSB-

pp.

-LSB-

-RSB-

AT&T

Microelectronics

Digital

Signal

Processor

Information

Manual

Allentown

-LRB-

Pennsylvania

USA

-RRB-

December

-LSB-

-RSB-

P.

J.

Brown

Macro

Processors

and

Techniques

for

Portable

Software

Wiley

London

-LRB-

UK

-RRB-

-LSB-

-RSB-

A.

J.

Cole

Macro

Processors

-LRB-

second

edition

-RRB-

Cambridge

University

Press

Cambridge

-LRB-

UK

-RRB-

-LSB-

-RSB-

A.

Dollas

and

J.

D.

S.

Babcock

Rapid

prototyping

of

microelectronic

systems

In

M.

C.

Yovits

and

M.

Zelkowitz

-LRB-

eds

-RRB-

Advances

in

Computers

vol

Academic

Press

San

Diego

-LRB-

California

USA

-RRB-

-LSB-

-RSB-

D.

J.

Farber

A

survey

of

the

systematic

use

of

macros

in

systems

building

ACM

SIGPLAN

Notices

vol

no.

pp.

October

-LSB-

-RSB-

J.

A.

Fisher

The

VLIW

machine

a

multiprocessor

for

compiling

scientioc

code

IEEE

Computer

vol

no.

pp.

July

-LSB-

-RSB-

I.

D.

Greenwald

A

technique

for

handling

macro

instructions

Communications

of

the

ACM

vol

no.

pp.

November

-LSB-

-RSB-

S.

M.

Kafka

An

assembly

source

level

global

compacter

for

digital

signal

processors

Proceedings

of

International

Conference

on

Acoustics

Speech

and

Signal

Processing

vol

pp

IEEE

Piscataway

-LRB-

New

Jersey

USA

-RRB-

-LSB-

-RSB-

K.

Kennedy

A

survey

of

data

AEow

analysis

techniques

In

S.

S.

Muchnik

and

N.

D.

Jones

-LRB-

eds

-RRB-

Program

Flow

Analysis

Theory

and

Applications

pp.

Prentice-Hall

Englewood

Clioes

-LRB-

New

Jersey

USA

-RRB-

-LSB-

-RSB-

B.

W.

Kernighan

and

D.

M.

Ritchie

The

C

Programming

Language

-LRB-

second

edition

-RRB-

Prentice-Hall

Englewood

Clioes

-LRB-

New

Jersey

USA

-RRB-

-LSB-

-RSB-

J.

R.

Larus

Assemblers

linkers

and

the

SPIM

simulator

In

J.

L.

Hennessy

and

D.

A.

Patterson

Computer

Organization

and

Design

The

Hardware/Software

Interface

Appendix

A.

Morgan

Kaufmann

San

Mateo

-LRB-

California

USA

-RRB-

-LSB-

-RSB-

E.

A.

Lee

Programmable

DSP

architectures

IEEE

ASSP

Magazine

vol

no.

pp.

-LRB-

Part

I

-RRB-

and

vol

no.

pp.

-LRB-

Part

II

-RRB-

October

and

January

-LSB-

-RSB-

J.

R.

Levine

T.

Mason

and

D.

Brown

Lex

yacc

-LRB-

second

edition

-RRB-

O'Reilly

Associates

Sebastopol

-LRB-

California

USA

-RRB-

-LSB-

-RSB-

P.

Marwedel

Code

generation

for

embedded

processors

an

introduction

In

-LSB-

-RSB-

pp.

-LSB-

-RSB-

P.

Marwedel

and

G.

Goossens

-LRB-

eds

-RRB-

Code

Generation

for

Embedded

Processors

Kluwer

Boston

-LRB-

Massachusetts

USA

-RRB-

-LSB-

-RSB-

M.

D.

McIlroy

Macro

instruction

extensions

of

compiler

languages

Communications

of

the

ACM

vol

no.

pp.

April

-LSB-

-RSB-

D.

A.

Patterson

Reduced

instruction

set

computers

Communications

of

the

ACM

vol

no.

pp.

January

-LSB-

-RSB-

D.

Salomon

Assemblers

and

Loaders

Ellis

Horwood

Chichester

-LRB-

UK

-RRB-

-LSB-

-RSB-

B.

Stroustrup

The

C++

Programming

Language

-LRB-

second

edition

-RRB-

Addison-Wesley

Reading

-LRB-

Massachusetts

USA

-RRB-

-LSB-

-RSB-

T.

Swan

Mastering

Turbo

Assembler

-LRB-

second

edition

-RRB-

Sams

Publishing

Indianapolis

-LRB-

Indiana

USA

-RRB-

-LSB-

-RSB-

W.

A.

Wulf

Compilers

and

computer

architecture

IEEE

Computer

vol

no.

pp.

July

code generation
macro expansion
program aeow analysis