/* Loglan82 Compiler&Interpreter Copyright (C) 1993 Institute of Informatics, University of Warsaw Copyright (C) 1993, 1994 LITA, Pau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. contacts: Andrzej.Salwicki@univ-pau.fr or Andrzej Salwicki LITA Departement d'Informatique Universite de Pau Avenue de l'Universite 64000 Pau FRANCE tel. ++33 59923154 fax. ++33 59841696 ======================================================================= */ #include "depend.h" #include "genint.h" #include "int.h" #include "process.h" #include "intproto.h" #include /* Execute one L-code instruction */ void execute() { word t1, t2; int i; real r; virtaddr virt1, virt2, virt3; #ifdef TRACE fprintf(stderr,"pix %d,ic %d,opcode %d\n",thispix,ic,opcode);fflush(stderr); #endif switch (opcode) { case 1 : /* LOPENRC */ openrc(a3, &virt2, &t2); storevirt(virt2, a1); M[ a2 ] = t2; break; case 2 : /* LBACKADDR */ storevirt(thisp->backobj, a1); M[ a2 ] = M[ temporary ]; break; case 3 : /* LRAISE */ ic++; /* skip the address */ raise_signal(a3, M[ ic-1 ], &t1, &t2); M[ a1 ] = t1; M[ a2 ] = t2; break; case 4 : /* LOPEN */ openobj(M[ a3 ], &t1, &t2); M[ a1 ] = t1; M[ a2 ] = t2; break; case 5 : /* LSLOPEN */ loadvirt(virt3, a3); slopen(M[ a3+APREF ], &virt3, &t1, &t2); M[ a1 ] = t1; M[ a2 ] = t2; break; case 15 : /* LTHIS */ virt1.addr = M[ display2+a2 ]; virt1.mark = M[ virt1.addr+1 ]; storevirt(virt1, a1); break; case 20 : /* LVIRTDISPL */ t2 = M[ display+a2 ]; t1 = M[ t2+PROTNUM ]; M[ a1 ] = M[ prototype[ t1 ]->virtlist+a3 ]; break; case 21 : /* LSTATTYPE */ M[ a1 ] = a2; M[ a1+1 ] = a3; break; case 23 : /* LIPAROUT */ M[ a1 ] = param[ a3 ].xword; break; case 24 : /* LRPAROUT */ MR(a1) = param[ a3 ].xreal; break; case 25 : /* LVPAROUT */ storevirt(param[ a3 ].xvirt, a1); break; case 31 : /* LSIGN */ if (M[ a2 ] == 0) M[ a1 ] = 0; else if (M[ a2 ] < 0) M[ a1 ] = -1; else M[ a1 ] = 1; break; case 33 : /* LLOWER */ case 34 : loadvirt(virt2, a2); if (member(&virt2, &t1)) { switch ((int) M[ t1+PROTNUM ]) { case AINT : t2 = APINT; break; case AREAL : t2 = APREAL; break; case AVIRT : t2 = APREF; break; } M[ a1 ] = (M[ t1+2 ]+3)/t2; } else errsignal(RTEREFTN); break; case 35 : /* LUPPER */ case 36 : loadvirt(virt2, a2); if (member(&virt2, &t1)) { switch ((int) M[ t1+PROTNUM ]) { case AINT : t2 = APINT; break; case AREAL : t2 = APREAL; break; case AVIRT : t2 = APREF; break; } M[ a1 ] = (M[ t1+2 ]+M[ t1 ])/t2-1; } else errsignal(RTEREFTN); break; case 40 : /* LGETTYPE */ typep(M[ a2 ], a3, &virt1.addr, &virt1.mark); storevirt(virt1, a1); break; case 41 : /* LCOPY */ loadvirt(virt2, a2); copy(&virt2, &virt1); storevirt(virt1, a1); break; case 42 : /* LNOT */ M[ a1 ] = ~ M[ a2 ]; break; case 43 : /* LRCVAVIRT */ /* recover virtual address from ah */ virt1.addr = M[ a2 ]; virt1.mark = M[ virt1.addr+1 ]; storevirt(virt1, a1); break; case 44 : /* LVIRTDOT */ case 45 : M[ a1 ] = M[ prototype[ M[ temporary ] ]->virtlist+a2 ]; break; case 46 : /* LADDRPH */ case 47 : /* LADDRPH2 */ loadvirt(virt2, a2); if (!member(&virt2, &M[ a1 ])) errsignal(RTEREFTN); break; case 48 : /* LIABS */ t2 = M[ a2 ]; M[ a1 ] = absolute(t2); break; case 49 : /* LINEG */ M[ a1 ] = -M[ a2 ]; break; case 50 : /* LRABS */ r = MR(a2); if( r < (real)0.0 ) r=(real)0.0-r; MR(a1) = r; break; case 51 : /* LRNEG */ MR(a1) = -MR(a2); break; case 52 : /* LPARAMADDR */ t2 = M[ a2 ]; M[ a1 ] = t2+M[ prototype[ M[ t2+PROTNUM ] ]->parlist+a3 ]; break; case 54 : /* LLOADT */ t1 = M[ ic++ ]; /* offset */ t2 = t1+loadt(M[ M[ a2 ] ], a3); /* object address */ loadvirt(virt1, t2); storevirt(virt1, a1); break; case 55 : /* LIS */ loadvirt(virt2, a2); M[ a1 ] = lbool(is(&virt2, a3)); break; case 56 : /* LIN */ loadvirt(virt2, a2); M[ a1 ] = lbool(inl(&virt2, a3)); break; case 57 : /* LQUA */ loadvirt(virt2, a2); if (member(&virt2, &M[ a1 ])) qua(&virt2, a3); else errsignal(RTEREFTN); break; case 58 : /* LIFIX */ M[ a1 ] = (word)( MR(a2) ); break; case 59 : /* LFLOAT */ MR(a1) = (real)( M[ a2 ] ); break; case 60 : /* LIMOVE */ M[ a1 ] = M[ a2 ]; break; case 61 : /* LVMOVE */ loadvirt(virt1, a2); storevirt(virt1, a1); break; case 62 : /* LRMOVE */ /* WARNING: these areas may overlap! */ r = MR(a2); MR(a1) = r; break; case 63 : /* LFPMOVE */ /* WARNING: these areas may overlap! */ loadvirt(virt1, a2); /* MACHINE DEPENDENT */ t1 = M[ a2+2 ]; storevirt(virt1, a1); M[ a1+2 ] = t1; break; case 82 : /* LEQNONE */ M[ a1 ] = lbool(M[ a2+1 ] != M[ M[ a2 ]+1 ]); break; case 83 : /* LNENONE */ M[ a1 ] = lbool(M[ a2+1 ] == M[ M[ a2 ]+1 ]); break; case 87 : /* LMDFTYPE */ /* modify the formal type */ loadvirt(virt1, a2); virt1.addr += a3; /* number of "arrayof" */ storevirt(virt1, a1); break; case 100 : /* LOR */ M[ a1 ] = M[ a2 ] | M[ a3 ]; break; case 101 : /* LAND */ M[ a1 ] = M[ a2 ] & M[ a3 ]; break; case 102 : /* LARRAY */ case 103 : case 104 : loadvirt(virt2, a2); if (member(&virt2, &t2)) { t1 = M[ a3 ]-M[ t2+2 ]; /* index-lower+3 */ if (t1 < 3 || t1 >= M[ t2 ]) errsignal(RTEINVIN); else M[ a1 ] = t2+t1; } else errsignal(RTEREFTN); break; case 105 : /* LFARRAY */ /* without any tests */ t1 = M[ M[ a2 ] ]; /* physical address */ M[ a1 ] = t1+M[ a3 ]-M[ t1+2 ]; break; case 106 : /* LIEQUAL */ M[ a1 ] = lbool(M[ a2 ] == M[ a3 ]); break; case 107 : /* LINEQUAL */ M[ a1 ] = lbool(M[ a2 ] != M[ a3 ]); break; case 108 : /* LILT */ M[ a1 ] = lbool(M[ a2 ] < M[ a3 ]); break; case 109 : /* LILE */ M[ a1 ] = lbool(M[ a2 ] <= M[ a3 ]); break; case 110 : /* LIGT */ M[ a1 ] = lbool(M[ a2 ] > M[ a3 ]); break; case 111 : /* LIGE */ M[ a1 ] = lbool(M[ a2 ] >= M[ a3 ]); break; case 112 : /* LCOMBINE */ loadvirt(virt2, a2); t1 = M[ a3 ]; storevirt(virt2, a1); M[ a1+APREF ] = t1; break; case 113 : /* LIADD */ M[ a1 ] = M[ a2 ]+M[ a3 ]; break; case 114 : /* LISUB */ M[ a1 ] = M[ a2 ]-M[ a3 ]; break; case 115 : /* LIMULT */ M[ a1 ] = M[ a2 ] * M[ a3 ]; break; case 116 : /* LSHIFT */ M[ a1 ] = shift(M[ a2 ], M[ a3 ]); break; case 117 : /* LIDIVE */ if (M[ a3 ] == 0) errsignal(RTEDIVBZ); else M[ a1 ] = M[ a2 ] / M[ a3 ]; break; case 118 : /* LIMODE */ if (M[ a3 ] == 0) errsignal(RTEDIVBZ); else M[ a1 ] = M[ a2 ] % M[ a3 ]; break; case 119 : /* LRADD */ MR(a1) = MR(a2)+MR(a3); break; case 120 : /* LRSUB */ MR(a1) = MR(a2)-MR(a3); break; case 121 : /* LRMULT */ MR(a1) = MR(a2) * MR(a3); break; case 122 : /* LRDIVE */ if (MR(a3) == (real)0.0) errsignal(RTEDIVBZ); else MR(a1) = MR(a2) / MR(a3); break; case 123 : /* LEQREF */ loadvirt(virt2, a2); loadvirt(virt3, a3); if (member(&virt2, &t1)) M[ a1 ] = lbool(member(&virt3, &t2) && t1 == t2); else M[ a1 ] = lbool(!member(&virt3, &t2)); break; case 124 : /* LNEREF */ loadvirt(virt2, a2); loadvirt(virt3, a3); if (member(&virt2, &t1)) M[ a1 ] = lbool(!member(&virt3, &t2) || t1 != t2); else M[ a1 ] = lbool(member(&virt3, &t2)); break; case 125 : /* LREQ */ M[ a1 ] = lbool(MR(a2) == MR(a3)); break; case 126 : /* LRNE */ M[ a1 ] = lbool(MR(a2) != MR(a3)); break; case 127 : /* LRLT */ M[ a1 ] = lbool(MR(a2) < MR(a3)); break; case 128 : /* LRLE */ M[ a1 ] = lbool(MR(a2) <= MR(a3)); break; case 129 : /* LRGT */ M[ a1 ] = lbool(MR(a2) > MR(a3)); break; case 130 : /* LRGE */ M[ a1 ] = lbool(MR(a2) >= MR(a3)); break; case 131 : /* LXOR */ M[ a1 ] = M[ a2 ] ^ M[ a3 ]; break; case 132 : /* LCALLPROCSTAND */ #if USE_ALARM alarm(0); /* reschedule forced so alarm may be switched off */ #endif reschedule=TRUE; standard(a1); break; case 143 : /* LKILL */ loadvirt(virt1, a1); disp(&virt1); break; case 144 : /* LHEADS */ loadvirt(virt1, a1); heads(&virt1, a2); break; case 145 : /* LIPARINP */ param[ a3 ].xword = M[ a1 ]; break; case 146 : /* LGKILL */ loadvirt(virt1, a1); gkill(&virt1); break; case 147 : /* LVPARINP */ loadvirt(param[ a3 ].xvirt, a1); break; case 148 : /* LRPARINP */ param[ a3 ].xreal = MR(a1); break; case 149 : /* LQUATEST */ loadvirt(virt1, a1); qua(&virt1, a2); break; case 150 : /* LSTYPE */ loadvirt(virt1, a1); typref(&virt1, a2); break; case 151 : /* LIFFALSE */ if (M[ a1 ] == LFALSE) ic = a2; break; case 152 : /* LIFTRUE */ if (M[ a1 ] == LTRUE) ic = a2; break; case 159 : /* LGO */ go(M[ a2 ], M[ a1 ]); break; case 160 : /* LGOLOCAL */ goloc(M[ a2 ], M[ a1 ]); break; case 170 : /* LDTYPE */ loadvirt(virt1, a1); /* left side type */ loadvirt(virt2, a2); loadvirt(virt3, a3); /* right side type */ typed(virt1.addr, virt1.mark, virt3.addr, virt3.mark, &virt2); break; case 172 : /* LTERMINATE */ term(); break; case 173 : /* LWIND */ wind(); break; case 174 : /* LBLOCK2 */ goloc(thisp->blck1, thisp->blck2); break; case 176 : /* LBLOCK3 */ disp(&thisp->backobj); break; case 177 : /* LTRACE */ trace(a1); break; case 178 : /* LINNER */ inner(a1); break; case 180 : /* LBACKHD */ backhd(&thisp->backobj, &M[ temporary ]); break; case 182 : /* LJUMP */ ic = a1; break; case 186 : /* LBLOCK1 */ openobj(a1, &thisp->blck1, &thisp->blck2); break; case 187 : /* LDETACH */ detach(); break; case 188 : /* LATTACH */ loadvirt(virt1, a1); attach(&virt1); break; case 191 : /* LBACKBL */ backbl(&thisp->backobj, &M[ temporary ]); break; case 192 : /* LBACKPR */ /* backpr(&thisp->backobj, &M[ temporary ]); */ back(&thisp->backobj, &M[ temporary ], (word) 0); break; case 193 : /* LBACK */ back(&thisp->backobj, &M[ temporary ], (word) 0); break; case 194 : /* LFIN */ fin(ic-APOPCODE, &thisp->backobj, &M[ temporary ]); break; case 195 : /* LCASE */ /* a2 = address of case description : */ /* minimal value, number of branches, */ /* remaining branches followed by "otherwise" code */ t1 = M[ a1 ]-M[ a2 ]; /* in 0..number of branches-1 */ if (t1 < 0 || t1 >= M[ a2+1 ]) ic = a2+2+M[ a2+1 ]; /* otherwise */ else ic = M[ a2+2+t1 ]; /* indirect jump */ break; case 220 : /* LRESUME */ loadvirt(virt1, a1); resume(&virt1); break; case 221 : /* LSTOP */ passivate(STOPPED); break; case 222 : /* LKILLTEMP */ disp(&thisp->template); break; case 223 : /* LENABLE */ for (i = 0; i < a1; i++) enable(thispix, virtprot(M[ ic++ ])); evaluaterpc(thispix); break; case 224 : /* LDISABLE */ for (i = 0; i < a1; i++) disable(thispix, virtprot(M[ ic++ ])); break; case 225 : /* LACCEPT1 */ rpc_accept(a1); break; case 226 : /* LACCEPT2 */ popmask(thispix); rpc3(); break; case 227 : /* LBACKRPC */ back(&thisp->backobj, &M[ temporary ], a1); break; case 228 : /* LASKPROT */ loadvirt(virt1, a1); askprot(&virt1); break; case 240 : /* LSTEP */ if (M[ a1 ] < 0) errsignal(RTENEGST); break; default : fprintf( stderr, "Invalid opcode\n" ); errsignal(RTESYSER); break; } } .