// Jouette.spec, created Tue Jun 29 15:52:41 1999 by pnkfelix
// Copyright (C) 1999 Felix S. Klock II <pnkfelix@mit.edu>
// Licensed under the terms of the GNU GPL; see COPYING for details.
package harpoon.Backend.Jouette;
import harpoon.ClassFile.HCodeElement;
import harpoon.ClassFile.HMethod;
import harpoon.ClassFile.HCode;
import harpoon.IR.Assem.Instr;
import harpoon.IR.Assem.InstrMEM;
import harpoon.IR.Assem.InstrFactory;
import harpoon.IR.Tree.Bop;
import harpoon.IR.Tree.Uop;
import harpoon.IR.Tree.Type;
import harpoon.IR.Tree.Typed;
import harpoon.Backend.Generic.DefaultFrame;
import harpoon.Backend.Generic.Code;
import harpoon.Util.Util;
import harpoon.Temp.Temp;
// normally a Code and Frame for a specific architecture would be in
// its own class accesible to other components of the system, but this
// is just an example illustrating how to write a spec file, not a
// whole backend. These are just stub-classes to let the "sensible"
// Instruction Patterns below be converted into compiliable Java
// source code.
class JouetteCode extends Code {
JouetteCode(HMethod m, Instr instrs, JouetteFrame frame) {
super(m, instrs, frame);
}
public HCode clone(HMethod hm)
throws CloneNotSupportedException {
throw new CloneNotSupportedException
("why are you trying to do something useful with JouetteCode");
}
public String getName() { return "jouette"; }
}
class JouetteFrame extends DefaultFrame {
public Temp regZero() { return getAllRegisters()[0]; }
}
// end of stub classes.
/**
* CodeGen
is a code-generator for the Jouette architecture.
*
* @see Appel, Modern Compiler Implementation in Java, pg. 196, 213-214
* @author Felix S. Klock II <pnkfelix@mit.edu>
* @version $Id: instr-selection-tool.html,v 1.2 2002/02/25 21:08:41 cananian Exp $
*/
%%
// FIELDS
// last = null OR last instr passed to emit(Instr)
private Instr last;
// InstrFactory to generate Instrs from
private InstrFactory inf;
// Frame for instructions to access to get platform specific variables (Register Temps, etc)
private JouetteFrame frame;
private void emit(Instr i) {
if (last == null) {
last = i;
} else {
last.insertInstrAfter(last, i);
last = i;
}
}
public CodeGen(JouetteCode code) {
last = null;
this.frame = (JouetteFrame) code.getFrame();
inf = code.getInstrFactory();
}
%%
/* this comment will be eaten by the .spec processor (unlike comments above) */
BINOP(ADD, j, k) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new Instr(inf, ROOT,
"ADD `d0 <- `s0 + `s1\n",
new Temp[]{ i }, new Temp[]{ j, k }));
}%
BINOP(MUL, j, k) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new Instr(inf, ROOT,
"MUL `d0 <- `s0 * `s1\n",
new Temp[]{ i }, new Temp[]{ j, k }));
}%
BINOP(SUB, j, k) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new Instr(inf, ROOT,
"SUB `d0 <- `s0 - `s1\n",
new Temp[]{ i }, new Temp[]{ j, k }));
}%
BINOP(DIV, j, k) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new Instr(inf, ROOT,
"SUB `d0 <- `s0 - `s1\n",
new Temp[]{ i }, new Temp[]{ j, k }));
}%
BINOP(ADD, j, CONST(c)) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new Instr(inf, ROOT,
"ADDI `d0 <- `s0 + " + c + "\n",
new Temp[]{ i }, new Temp[]{ j }));
}%
// need to manually represent symmetry by repeating patterns
BINOP(ADD, CONST(c), j) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new Instr(inf, ROOT,
"ADDI `d0 <- `s0 + " + c + "\n",
new Temp[]{ i }, new Temp[]{ j }));
}%
CONST(c) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new Instr(inf, ROOT,
"ADDI `d0 <- `s0 + " + c + "\n",
new Temp[]{ i }, new Temp[]{ frame.regZero() }));
}%
BINOP(SUB, j, CONST(c)) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new Instr(inf, ROOT,
"SUBI `d0 <- `s0 - " + c + "\n",
new Temp[]{ i }, new Temp[]{ j }));
}%
MEM(BINOP(ADD, j, CONST(c))) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new InstrMEM(inf, ROOT,
"LOAD `d0 <- M[`s0 + " + c + "]\n",
new Temp[] { i }, new Temp[]{ j }));
}%
MEM(BINOP(ADD, CONST(c), j)) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new InstrMEM(inf, ROOT,
"LOAD `d0 <- M[`s0 + " + c + "]\n",
new Temp[] { i }, new Temp[]{ j }));
}%
MEM(CONST(c)) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new InstrMEM(inf, ROOT,
"LOAD `d0 <- M[`s0 + " + c + "]\n",
new Temp[] { i }, new Temp[]{ frame.regZero() }));
}%
MEM(j) = i %{
Temp i = new Temp(frame.tempFactory());
emit(new InstrMEM(inf, ROOT,
"LOAD `d0 <- M[`s0 + 0]\n",
new Temp[] { i }, new Temp[]{ j }));
}%
MOVE(MEM(BINOP(ADD, j, CONST(c))), src) %{
Temp i = new Temp(frame.tempFactory());
emit(new InstrMEM(inf, ROOT,
"STORE M[`s0 + " + c + "] <- `s1\n",
new Temp[] { }, new Temp[] { j, src }));
}%
MOVE(MEM(BINOP(ADD, CONST(c), j)), src) %{
Temp i = new Temp(frame.tempFactory());
emit(new InstrMEM(inf, ROOT,
"STORE M[`s0 + " + c + "] <- `s1\n",
new Temp[] { }, new Temp[] { j, src }));
}%
MOVE(MEM(CONST(c)), src) %{
Temp i = new Temp(frame.tempFactory());
emit(new InstrMEM(inf, ROOT,
"STORE M[`s0 + " + c + "] <- `s1\n",
new Temp[] { }, new Temp[] { frame.regZero(), src }));
}%
MOVE(MEM(target), src) %{
Temp i = new Temp(frame.tempFactory());
emit(new InstrMEM(inf, ROOT,
"STORE M[`s0 + 0] <- `s1\n",
new Temp[] { }, new Temp[] { target, src }));
}%
MOVE(MEM(target), MEM(src)) %{
Temp i = new Temp(frame.tempFactory());
emit(new Instr(inf, ROOT,
"MOVE M[`s0] <- M[`s1]\n",
new Temp[] {}, new Temp[] { target, src }));
}%
EXPR(e1) %{
/* this is a statement that's just an
expression; just throw away
calculated value */
}%