Text Slask_Register="%i5"; Text Slask_Register2="%i4"; Procedure DDT(t);Text t; Begin End; Text Procedure register(val);Integer val; Begin Text t; % OutText("register(");OutInt(val,0);OutText(")="); t:-Blanks(3); If val<=8 Then Begin t.SetPos(3); t.putint(val-1); t.SetPos(2); t.PutChar('l'); End Else Begin t.SetPos(3); t.putint(val-8); % Kan även vara g1 tom g6; t.SetPos(2); t.PutChar('g'); If val>(6+8) Then Error("Slut på register \n skriv mindre uttryck, mellanlagra i variabler eller skaffa större CPU"); End; t.SetPos(1); t.PutChar('%'); % OutText(t);OutImage; register:-t; End; Text Procedure Parreg(val);Integer val; Begin Text t; % OutText("ParReg(");OutInt(val,0);OutText(")="); t:-Blanks(3); If val<=4 or val=7 Then Begin t.SetPos(3); t.putint(val); t.SetPos(2); t.PutChar('i'); End Else Begin val:=if val>7 then val-5 else val-4; % 1 2 3 4 5 t.SetPos(3); t.putint(val); % Kan även vara o1 tom o5; t.SetPos(2); t.PutChar('o'); if val>=6 then error("ASM: To few CPU registers replace CPU and retry"); End; t.SetPos(1); t.PutChar('%'); % outtext(t);OutImage; Parreg:-t; End; Procedure atext(Txt);Text txt; Begin sourcecode.OutText(txt); End; Procedure aint(nr,nr2);Integer nr,nr2; Begin sourcecode.OutInt(nr,nr2); End; Procedure achar(ch);Character ch; Begin sourcecode.Outchar(ch); End; Procedure aout; Begin sourcecode.Outimage; End; Procedure ttext(Txt);Text txt; Begin actoutfile__.OutText(txt); End; Procedure tint(nr,nr2);Integer nr,nr2; Begin actoutfile__.OutInt(nr,nr2); End; Procedure tchar(ch);Character ch; Begin actoutfile__.Outchar(ch); End; Procedure tout; Begin actoutfile__.Outimage; End; Procedure AsmNop; Begin AChar(Tab); AText("nop"); AOut; End; class arg(Type);Integer Type; virtual: procedure treadd is procedure treadd;; procedure asm is procedure asm;; procedure getasm Is Text procedure getasm;; begin end; arg class TempArg(val);integer val; begin procedure treadd; begin ttext("#"); tint(val,0); end; procedure asm; Begin Atext(Register(val)); end; Text Procedure getasm; Begin getasm:-register(val); End; end; arg class IdArg(VD);Ref(VarDes) VD; begin procedure treadd; begin ttext(VD.getvarname); end; procedure asm; begin !info AText(VD.getvarname&VD.lab); AText(vd.lab); end; Text procedure getasm; !info getasm:-VD.getvarname&VD.lab; getasm:-VD.lab; End; IdArg class StIdArg(rel);Integer rel; begin procedure asm; begin AText("[%g7+"); AInt(rel,0); Atext("]"); end; End; arg class LabelArg(val);text val; Begin procedure treadd; begin ttext(val); end; procedure asm; begin AText(val); end; Text Procedure getasm; getasm:-val; End; arg class TextArg(val);text val; Begin procedure treadd; Begin tchar('"'); ttext(val); tchar('"'); end; procedure asm; Begin Achar('"'); AText(val); Achar('"'); End; Text Procedure getasm; getasm:-val; End; arg class RegArg(val);text val; ! -- goes down to the asembler untouched; Begin ! This is not platformindependendent; procedure treadd; begin ttext(val); end; procedure asm; begin AText(val); end; Text Procedure getasm; getasm:-val; End; arg class ConstArg(val);integer val; begin procedure treadd; begin tint(val,0); end; procedure asm; Begin % If val=0 Then % AText("%g0") % Else % Begin aint(val,0); % End; end; End; link class OpCode(namnet);text namnet; virtual: procedure treadd is procedure treadd;; procedure asm is procedure asm;; procedure FixAsm is procedure FixAsm;; begin end; OpCode class Op0; begin procedure treadd; begin tchar(Tab); ttext(namnet); tout; end; procedure asm; begin End; procedure FixAsm; begin end; end; OpCode class Op1(p1); ref(arg) p1; begin procedure treadd; begin tchar(Tab); ttext(namnet); tchar(Tab); p1.treadd; tout; end; procedure asm; begin End; procedure FixAsm; begin end; end; OpCode class Op2(p1,p2); ref(arg) p1,p2; begin procedure treadd; begin tchar(Tab); ttext(namnet); tchar(Tab); p1.treadd; tchar(Tab); p2.treadd; tout; end; procedure asm; begin End; procedure FixAsm; begin end; end; OpCode class Op3(p1,p2,p3); ref(arg) p1,p2,p3; begin procedure treadd; begin tchar(Tab); ttext(namnet); tchar(Tab); p1.treadd; tchar(Tab); p2.treadd; tchar(Tab); p3.treadd; tout; end; procedure asm; begin End; procedure FixAsm; begin end; end; op0 Class ALabel; Begin procedure treadd; begin ttext(namnet&":");tout; End; procedure asm; begin AText(namnet&":");aout; end; End; op1 Class ADeclar; Begin procedure treadd; begin ttext(namnet&":"); tchar(Tab); tText(".word"); tchar(Tab); p1.treadd; tout; End; procedure asm; begin atext(namnet&":"); achar(Tab); aText(".word"); achar(Tab); p1.asm; AOut; end; End; op1 Class ADeclartxt; Begin procedure treadd; begin ttext(namnet&":"); tchar(Tab); tText(".asciz"); tchar(Tab); p1.treadd; tout; End; procedure asm; begin atext(namnet&":"); achar(Tab); aText(".asciz"); achar(Tab); p1.asm; AOut; end; End; op0 class nop; begin procedure asm; begin AChar(Tab); AText("nop"); AOut; end; End; op1 Class AsmWriteInt; begin procedure asm; Begin achar(Tab);atext("mov"); achar(Tab);p1.asm; achar(nxx);atext("%o0"); aOut; achar(Tab);atext("mov"); achar(Tab);atext("0,%o1"); !antalet positionen , hårdkodat; aOut; achar(Tab);atext("call"); achar(Tab);atext("writeint"); aOut; AsmNop; End; End; op1 Class AsmWriteText; Begin Text t1; procedure asm; Begin achar(Tab);atext("set"); achar(Tab);atext(t1); achar(nxx);atext("%o0"); aOut; achar(Tab);atext("call"); achar(Tab);atext("writestring"); aOut; AsmNop; End; Procedure FixAsm; Begin emit2(new ADeclartxt(t1,p1)); emit2(new AAlign("Align",New ConstArg(INTE,4))); End; t1:-GetNewLabel; End; op1 Class Abeq; begin procedure asm; begin AChar(Tab); AText("be"); AChar(Tab); p1.asm; AOut; AsmNop; end; End; op1 Class AAlign; begin procedure asm; begin AChar(Tab); AText(".align"); AChar(Tab); p1.asm; AOut; end; End; op1 Class AsmCall; begin procedure asm; Begin achar(Tab);atext("call"); achar(Tab);p1.asm; % achar(Tab);atext("! call --------------"); aOut; End; End; op1 Class Atst; begin procedure asm; begin AChar(Tab); AText("tst"); AChar(Tab); p1.asm; AOut; end; End; op1 Class Abne; begin procedure asm; begin AChar(Tab); AText("bne"); AChar(Tab); p1.asm; AOut; AsmNop; end; End; op1 Class AGoto; begin procedure asm; begin achar(Tab); atext("set"); achar(Tab); p1.asm; achar(nxx); atext(Slask_Register); achar(Tab); atext("!GOTO"); aOut; achar(Tab); atext("jmp"); achar(Tab); atext(Slask_Register); aOut; AsmNop; end; End; op1 Class Aneg; begin procedure asm; begin AChar(Tab); AText("neg"); AChar(Tab); p1.asm; AOut; end; End; op1 Class Anot; begin procedure asm; begin AChar(Tab); AText("not"); AChar(Tab); p1.asm; AOut; end; End; op2 class Move; Begin Text myla; procedure asm; Begin If p2 Is regarg Or p2 Is temparg Then begin If P1 Is regarg Or p1 Is temparg Then Begin If p1 Is temparg And p2 Is temparg And Then (p1 Qua temparg.val = p2 Qua temparg.val) Then Begin aText("!"); AChar(Tab); AText("mov"); AChar(Tab); p1.asm; AChar(nxx); p2.asm; Atext("---------------------Removed a move, Optimized"); AOut; End Else begin AChar(Tab); AText("mov"); AChar(Tab); p1.asm; AChar(nxx); p2.asm; aOut; end; End Else If P1 Is constarg Then Begin If (p1 Qua constarg).val<8192 Then Begin AChar(Tab); AText("mov"); AChar(Tab); p1.asm; AChar(nxx); p2.asm; AOut; End Else Begin AChar(Tab); AText("set"); AChar(Tab); Atext(myla); AChar(nxx); Atext(Slask_Register); Aout; AChar(Tab); AText("ld"); AChar(Tab); Atext("["&Slask_Register&"]"); AChar(nxx); p2.asm; AOut; End; End Else If p1 Is Idarg Then Begin AChar(Tab); AText("set"); AChar(Tab); p1.asm; AChar(nxx); Atext(Slask_Register); Aout; AChar(Tab); AText("ld"); AChar(Tab);Atext("["&Slask_Register&"]"); AChar(nxx);p2.asm; AOut; End Else If p1 Is stidarg Then Begin Text t; t:-Blanks(5); t.PutInt(p1 Qua stidarg.rel); atext("ld");AChar(Tab);p1.asm;achar(nxx);p2.asm;aout; End Else ddt("Fel 1"); End Else If p2 Is Labelarg Or p2 Is idarg Then Begin If p1 Is temparg Or p1 Is regarg Then Begin AChar(Tab); AText("set"); AChar(Tab); p2.asm; AChar(nxx); Atext(Slask_Register); Aout; AChar(Tab); AText("st"); AChar(Tab); p1.asm; AChar(nxx); Atext("["&Slask_Register&"]"); Aout; End Else If p1 Is idarg Or p1 Is labelarg Or p1 Is stidarg Then Begin AChar(Tab); AText("ld"); AChar(Tab); p1.asm; AChar(nxx); Atext(Slask_Register); Aout; AChar(Tab); AText("set"); AChar(Tab); p2.asm; AChar(nxx); Atext(Slask_Register2); Aout; AChar(Tab); AText("st"); AChar(Tab); Atext(Slask_Register); AChar(nxx); Atext("["&Slask_Register2&"]"); Aout; End; End Else If p2 Is StIdArg Then Begin If p1 Is temparg Or p1 Is regarg Then Begin AChar(Tab); AText("st"); AChar(Tab); p1.asm; AChar(nxx); p2.asm; Aout; End Else If p1 Is idarg Or p1 Is labelarg Then Begin AChar(Tab); AText("ld"); AChar(Tab); p1.asm; AChar(nxx); Atext(Slask_Register); Aout; AChar(Tab); AText("st"); AChar(Tab); Atext(Slask_Register); AChar(nxx); p2.asm; Aout; End; End Else ddt("FEL"); End; Procedure FixAsm; Begin If P1 Is constarg Then Begin If (p1 Qua constarg).val<8192 Then Begin End Else Begin myla:-getnewlabel; emit2(new ADeclar(myla,p1)); End; End End; End; op3 class Add; begin procedure asm; begin AChar(Tab); AText("add"); AChar(Tab); p1.asm; AChar(nxx); p2.asm; AChar(nxx); p3.asm; AOut; end; end; op3 class Sub; begin procedure asm; begin AChar(Tab); AText("sub"); AChar(Tab); p1.asm; AChar(nxx); p2.asm; AChar(nxx); p3.asm; AOut; end; End; op3 class MUL; begin procedure asm; Begin AChar(Tab); AText("mov"); AChar(Tab); p1.asm; AChar(nxx); AText("%o0"); aout; AChar(Tab); AText("mov"); AChar(Tab); p2.asm; AChar(nxx); AText("%o1"); AOut; AChar(Tab);AText("call"); AChar(Tab); AText(".mul"); AOut; asmnop; AChar(Tab); AText("mov"); AChar(Tab); AText("%o0"); AChar(nxx); p3.asm; % AChar(Tab); AText("! Mul End -------------------------------"); AOut; end; End; op3 class Div; begin procedure asm; Begin AChar(Tab); AText("mov"); AChar(Tab); p1.asm; AChar(nxx); AText("%o0");aout; AChar(Tab); AText("mov"); achar(Tab); p2.asm; achar(nxx); AText("%o1"); aout; AChar(Tab);AText("call"); AChar(Tab); AText(".div"); AOut; asmnop; achar(Tab); AText("mov"); achar(Tab); AText("%o0"); achar(nxx); p3.asm; % achar(Tab); AText("! Div End -------------------------------"); aout; end; End; op3 class Aor; begin procedure asm; begin achar(Tab); atext("or"); achar(Tab); p1.asm; achar(nxx); p2.asm; achar(nxx); p3.asm; aout; end; End; op3 class Aand; begin procedure asm; begin achar(Tab); atext("and"); achar(Tab); p1.asm; achar(nxx); p2.asm; achar(nxx); p3.asm; aout; end; End; op3 class cmp; begin procedure asm; Begin Text lab1,lab2; lab1:-GetNewLabel; lab2:-GetNewLabel; AChar(Tab); AText("cmp"); AChar(Tab); p1.asm; AChar(nxx); p2.asm; % AChar(Tab); AText("! CMP-----------------------------------"); AOut; AChar(Tab); AText("be"); AChar(Tab); AText(lab1); !TRUE; AOut; AsmNop; AChar(Tab); AText("set"); AChar(Tab); AText(lab2); AChar(nxx); AText(Slask_Register); AOut; AChar(Tab); AText("jmp"); AChar(Tab); AText(Slask_Register); AOut; AChar(Tab); AText("mov"); AChar(Tab); AText("0"); AChar(nxx); p3.asm; AChar(Tab); AText("! preformed befor the jmp"); AOut; AText(lab1&":"); AChar(Tab); AText("mov"); AChar(Tab); AText("-1"); AChar(nxx); p3.asm; % AChar(Tab); AText("! cmp end------------"); AOut; AText(lab2&":"); end; End; op3 class Alt; begin procedure asm; Begin Text lab1,lab2; lab1:-GetNewLabel; lab2:-GetNewLabel; AChar(Tab); AText("cmp"); AChar(Tab); p1.asm; AChar(nxx); p2.asm; % AChar(Tab); AText("! LT -----------------------------------"); AOut; AChar(Tab); AText("bl"); AChar(Tab); AText(lab1); !TRUE; AOut; AsmNop; AChar(Tab); AText("set"); AChar(Tab); AText(lab2); AChar(nxx); AText(Slask_Register); AOut; AChar(Tab); AText("jmp"); AChar(Tab); AText(Slask_Register); AOut; AChar(Tab); AText("mov"); AChar(Tab); AText("%g0"); AChar(nxx); p3.asm; AChar(Tab); AText("! preformed befor the jmp"); AOut; AText(lab1&":"); AChar(Tab); AText("mov"); AChar(Tab); AText("-1"); AChar(nxx); p3.asm; % AChar(Tab); AText("! LT End-------------------------------"); AOut; AText(lab2&":"); end; End; op3 class Agt; begin procedure asm; Begin Text lab1,lab2; lab1:-GetNewLabel; lab2:-GetNewLabel; AChar(Tab); AText("cmp"); AChar(Tab); p1.asm; AChar(nxx); p2.asm; % AChar(Tab); AText("! GT -----------------------------------"); AOut; AChar(Tab); AText("bg"); AChar(Tab); AText(lab1); !TRUE; AOut; AsmNop; AChar(Tab); AText("set"); AChar(Tab); AText(lab2); AChar(nxx); AText(Slask_Register); !---- OBS Registercalc neaded; AOut; AChar(Tab); AText("jmp"); AChar(Tab); AText(Slask_Register); AOut; AChar(Tab); AText("mov"); AChar(Tab); AText("0"); AChar(nxx); p3.asm; AChar(Tab); AText("! preformed befor the jmp"); AOut; AText(lab1&":"); AChar(Tab); AText("mov"); AChar(Tab); AText("-1"); AChar(nxx); p3.asm; % AChar(Tab); AText("! GT End------------------------------"); AOut; AText(lab2&":"); end; End; op0 Class Aallochead; begin procedure asm; Begin achar(TAB);atext("sub %g7,56,%g7");aOut; achar(TAB);atext("st %l0,[%g7+0]");aOut; achar(TAB);atext("st %l1,[%g7+4]");aOut; achar(TAB);atext("st %l2,[%g7+8]");aOut; achar(TAB);atext("st %l3,[%g7+12]");aOut; achar(TAB);atext("st %l4,[%g7+16]");aOut; achar(TAB);atext("st %l5,[%g7+20]");aOut; achar(TAB);atext("st %l6,[%g7+24]");aOut; achar(TAB);atext("st %l7,[%g7+28]");aOut; achar(TAB);atext("st %g1,[%g7+32]");aOut; achar(TAB);atext("st %g2,[%g7+36]");aOut; achar(TAB);atext("st %g3,[%g7+40]");aOut; achar(TAB);atext("st %g4,[%g7+44]");aOut; achar(TAB);atext("st %g5,[%g7+48]");aOut; achar(TAB);atext("st %g6,[%g7+52]");aOut; achar(TAB);atext("add %g7,56,%g7");aOut; end; End; op1 Class Aallocfunc; begin procedure asm; Begin achar(Tab);atext("sub"); achar(Tab);atext("%g7,");p1.asm;atext(",%g7"); achar(Tab);atext("! allocfunc"); aOut; end; End; op1 Class ADeAllocfunc; begin procedure asm; Begin achar(Tab);atext("add"); achar(Tab);atext("%g7,");p1.asm;atext(",%g7"); achar(Tab);atext("! Deallocfunc"); aout; end; end; op1 Class Aparam(i);Integer i; begin procedure asm; Begin (New move("InternSymbol",p1,New regarg(INTE,parreg(i)))).asm end; end; op1 Class ACall(stl);Integer stl; Begin Procedure asm; Begin achar(TAB);atext("sub %g7,60,%g7");aOut; stl:=4*stl; achar(Tab);atext("set"); achar(Tab);atext("1f,%g5"); aout; achar(TAB);atext("st");achar(TAB);atext("%g5");achar(nxx);atext("[%g7]");aout; achar(Tab);atext("set"); achar(Tab);p1.asm;atext(",%g5"); aOut; achar(Tab);atext("jmp"); achar(Tab);atext("%g5"); aOut; achar(Tab);atext("sub %g7,4,%g7"); !-- Räkna upp stack pekare innan hoppet; achar(Tab); aOut; atext("1:");aOut; achar(TAB);atext("ld [%g7+4],%l0");aOut; achar(TAB);atext("ld [%g7+8],%l1");aOut; achar(TAB);atext("ld [%g7+12],%l2");aOut; achar(TAB);atext("ld [%g7+16],%l3");aOut; achar(TAB);atext("ld [%g7+20],%l4");aOut; achar(TAB);atext("ld [%g7+24],%l5");aOut; achar(TAB);atext("ld [%g7+28],%l6");aOut; achar(TAB);atext("ld [%g7+32],%l7");aOut; achar(TAB);atext("ld [%g7+36],%g1");aOut; achar(TAB);atext("ld [%g7+40],%g2");aOut; achar(TAB);atext("ld [%g7+44],%g3");aOut; achar(TAB);atext("ld [%g7+48],%g4");aOut; achar(TAB);atext("ld [%g7+52],%g5");aOut; achar(TAB);atext("ld [%g7+56],%g6");aOut; achar(TAB);atext("add %g7,60,%g7");aout; !-- Ja det skall vara 60 här; end; End; op1 Class fununload(a);Integer a; Begin Procedure asm; begin (New move("InternSymbol",New regarg(INTE,parreg(a)),p1)).asm; End; End; op0 Class AReturn; begin procedure asm; Begin achar(Tab);atext("ld"); achar(Tab);atext("[%g7+4]");achar(nxx);atext(Slask_register); aOut; achar(Tab);atext("jmp"); achar(Tab);atext(Slask_register); aOut; achar(Tab);atext("add"); achar(Tab);atext("%g7,4,%g7"); aOut; End; End; op1 Class Adealloc; begin procedure asm; begin % achar(Tab); atext("dealloc"); % achar(Tab); p1.asm; % aOut; end; end; op1 Class Afunload; begin procedure asm; Begin (New move("InternSymbol",p1,new regarg(INTE,"%o0"))).asm; aOut; end; end; op1 Class Afunstore; begin procedure asm; Begin % achar(Tab); atext("mov"); % achar(Tab); atext("%o0"); % achar(nxx); p1.asm; % achar(Tab); atext("!funstore Lagra %o0 i rätt variabel"); % aOut; (New move("InternSymbol",New regarg(INTE,"%o0"),p1)).asm end; End; Procedure initAsm; Begin % atext("dyn_rel = 0");aout; % atext("stat_rel = 4");aout; % atext("ret_rel = 8");aout; achar(Tab);atext(".seg"); achar(Tab);achar('"');atext("data");achar('"'); % achar(Tab);atext("! Init-rutine first in prog"); aout; achar(tab);atext(".skip");achar(Tab);atext("4096");aout; atext("stack:"); achar(Tab);atext(".word 0");aout; % atext("!-- allt som behövs deklareras plats till."); aout; End; Procedure initText; begin achar(Tab);atext(".seg"); achar(Tab);achar('"');atext("text");achar('"'); achar(Tab); % atext("! Init-rutine first in prog"); aout; achar(Tab);atext(".global"); achar(Tab);atext("main"); aout; atext("main:"); achar(Tab);atext("set"); achar(Tab);atext("stack,%g7"); achar(Tab);atext("! %g7 till stacken"); aout; atext("!-- Programmet."); aout; End; Procedure endAsm; begin achar(Tab);atext("call"); achar(Tab);atext("_exit"); aout; achar(Tab);atext("nop"); % achar(Tab);atext("! --- Programmet är nu slut"); aout; End;