Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/vm/instruction/instgen.cc

Go to the documentation of this file.
00001 /*
00002  * vm/instruction/instgen.cc
00003  * 
00004  * VM instruction storage: Instruction generation. 
00005  * 
00006  * Copyright (c) 2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00007  * 
00008  * This file may be distributed and/or modified under the terms of the 
00009  * GNU General Public License version 2 as published by the Free Software 
00010  * Foundation. (See COPYING.GPL for details.)
00011  * 
00012  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014  * 
00015  */
00016 
00017 #include "storage.h"
00018 #include <lib/message/message.h>
00019 
00020 
00021 namespace VM
00022 {
00023 
00024 static void _AssertAC_Fail(const INST::DescEntry *d,
00025     INST::IID inst,INST::ArgComb ac);
00026 
00027 inline void _AssertAC(INST::IID inst,INST::ArgComb ac)
00028 {
00029     const INST::DescEntry *d=INST::Desc(inst);
00030     
00031     // These are acutally programming errors!
00032     if(!d || d->argcomb!=ac)  _AssertAC_Fail(d,inst,ac);
00033 }
00034 
00035 static void _AssertAC_Fail(const INST::DescEntry *d,
00036     INST::IID inst,INST::ArgComb ac)
00037 {
00038     if(!d)
00039     {  Fatal("illegal instruction %d",(int)inst);  }
00040     else if(d->argcomb!=ac)
00041     {  Fatal("illegal arg comb %d instead of %d for instruction %s",
00042         (int)ac,(int)d->argcomb,d->name);  }
00043     
00044     // Be sure...
00045     Assert(0);
00046 }
00047 
00048 
00049 template<typename T>static inline void IPush(char * &mem,const T &val)
00050 {
00051     *(T*)mem=val;
00052     mem+=sizeof(T);
00053 }
00054 
00055 template<typename T>static inline void IPop(const char * &mem,T *val)
00056 {
00057     if(val) *val=*(T*)mem;
00058     mem+=sizeof(T);
00059 }
00060 
00061 
00062 static void _SizeAssertFail(INST::IID inst,size_t stored,size_t allocated)
00063 {
00064     const INST::DescEntry *d=INST::Desc(inst);
00065     Fatal("size mismatch for %s: size=%u, stored=%u, allocated=%u",
00066         d->name,d->size,(uint)stored,(uint)allocated);
00067     
00068     // Be sure...
00069     Assert(0);
00070 }
00071 
00072 static void _SizeAssertFail2(INST::IID inst,size_t read)
00073 {
00074     const INST::DescEntry *d=INST::Desc(inst);
00075     Fatal("size mismatch for %s: size=%u, read=%u",
00076         d->name,d->size,(uint)read);
00077     
00078     // Be sure...
00079     Assert(0);
00080 }
00081 
00082 // Ugly macro for size checking. 
00083 #define SIZECHECK \
00084     if(m-(char*)mem!=sizeof(mem) || sizeof(mem)!=INST::Desc(inst)->size)  \
00085     {  _SizeAssertFail(inst,m-(char*)mem,sizeof(mem));  }
00086 
00087 // Second ugly macro for size checking. 
00088 #define SIZECHECK2 \
00089     if(m-mem!=INST::Desc(inst)->size)  \
00090     {  _SizeAssertFail2(inst,m-mem);  }
00091 
00092 //------------------------------------------------------------------------------
00093 
00094 void InstructionStorage::append(INST::IID inst)
00095 {
00096     _AssertAC(inst,INST::AC_void);
00097     
00098     uint16 mem[1];
00099     char *m=(char*)mem;
00100     
00101     IPush(m, (uint16)inst);
00102     
00103     SIZECHECK
00104     append((char*)mem,INST::Desc(inst)->size);
00105 }
00106 
00107 void InstructionStorage::append(INST::IID inst,uint32 a)
00108 {
00109     _AssertAC(inst,INST::AC_i);
00110     
00111     uint16 mem[3];
00112     char *m=(char*)mem;
00113     
00114     IPush(m, (uint16)inst);
00115     IPush(m, a);
00116     
00117     SIZECHECK
00118     append((char*)mem,INST::Desc(inst)->size);
00119 }
00120 
00121 void InstructionStorage::append(INST::IID inst,int32 a)
00122 {
00123     _AssertAC(inst,INST::AC_S);
00124     
00125     uint16 mem[3];
00126     char *m=(char*)mem;
00127     
00128     IPush(m, (uint16)inst);
00129     IPush(m, a);
00130     
00131     SIZECHECK
00132     append((char*)mem,INST::Desc(inst)->size);
00133 }
00134 
00135 void InstructionStorage::append(INST::IID inst,uint8 a,uint8 b)
00136 {
00137     _AssertAC(inst,INST::AC_bb);
00138     
00139     uint16 mem[2];
00140     char *m=(char*)mem;
00141     
00142     IPush(m, (uint16)inst);
00143     IPush(m, a);
00144     IPush(m, b);
00145     
00146     SIZECHECK
00147     append((char*)mem,INST::Desc(inst)->size);
00148 }
00149 
00150 void InstructionStorage::append(INST::IID inst,uint16 a,uint8 b)
00151 {
00152     _AssertAC(inst,INST::AC_sb);
00153     
00154     uint16 mem[3];
00155     char *m=(char*)mem;
00156     IPush(m, (uint16)inst);
00157     IPush(m, a);
00158     IPush(m, b);
00159     IPush(m, uint8(0));
00160     
00161     SIZECHECK
00162     append((char*)mem,INST::Desc(inst)->size);
00163 }
00164 
00165 void InstructionStorage::append(INST::IID inst,uint32 a,uint8 b)
00166 {
00167     _AssertAC(inst,INST::AC_ib);
00168     
00169     uint32 mem[2];
00170     char *m=(char*)mem;
00171     IPush(m, (uint16)inst);
00172     IPush(m, b);
00173     IPush(m, uint8(0));
00174     IPush(m, a);
00175     
00176     SIZECHECK
00177     append((char*)mem,INST::Desc(inst)->size);
00178 }
00179 
00180 void InstructionStorage::append(INST::IID inst,int32 a,uint8 b)
00181 {
00182     _AssertAC(inst,INST::AC_Sb);
00183     
00184     uint32 mem[2];
00185     char *m=(char*)mem;
00186     IPush(m, (uint16)inst);
00187     IPush(m, b);
00188     IPush(m, uint8(0));
00189     IPush(m, a);
00190     
00191     SIZECHECK
00192     append((char*)mem,INST::Desc(inst)->size);
00193 }
00194 
00195 void InstructionStorage::append(INST::IID inst,uint64 a,uint8 b)
00196 {
00197     _AssertAC(inst,INST::AC_lb);
00198     
00199     uint32 mem[3];
00200     char *m=(char*)mem;
00201     
00202     IPush(m, (uint16)inst);
00203     IPush(m, b);
00204     IPush(m, uint8(0));
00205     IPush(m, a);
00206     
00207     SIZECHECK
00208     append((char*)mem,INST::Desc(inst)->size);
00209 }
00210 
00211 void InstructionStorage::append(INST::IID inst,flt a,uint8 b)
00212 {
00213     _AssertAC(inst,INST::AC_fb);
00214     
00215     uint32 mem[2];
00216     char *m=(char*)mem;
00217     
00218     IPush(m, (uint16)inst);
00219     IPush(m, b);
00220     IPush(m, uint8(0));
00221     IPush(m, a);
00222     
00223     SIZECHECK
00224     append((char*)mem,INST::Desc(inst)->size);
00225 }
00226 
00227 void InstructionStorage::append(INST::IID inst,flt a,flt b,uint8 z)
00228 {
00229     _AssertAC(inst,INST::AC_ffb);
00230     
00231     uint32 mem[3];
00232     char *m=(char*)mem;
00233     
00234     IPush(m, (uint16)inst);
00235     IPush(m, z);
00236     IPush(m, uint8(0));
00237     IPush(m, a);
00238     IPush(m, b);
00239     
00240     SIZECHECK
00241     append((char*)mem,INST::Desc(inst)->size);
00242 }
00243 
00244 void InstructionStorage::append(INST::IID inst,flt a,flt b,flt c,uint8 z)
00245 {
00246     _AssertAC(inst,INST::AC_fffb);
00247     
00248     uint32 mem[4];
00249     char *m=(char*)mem;
00250     
00251     IPush(m, (uint16)inst);
00252     IPush(m, z);
00253     IPush(m, uint8(0));
00254     IPush(m, a);
00255     IPush(m, b);
00256     IPush(m, c);
00257     
00258     SIZECHECK
00259     append((char*)mem,INST::Desc(inst)->size);
00260 }
00261 
00262 void InstructionStorage::append(INST::IID inst,flt a,flt b,flt c,flt d,uint8 z)
00263 {
00264     _AssertAC(inst,INST::AC_ffffb);
00265     
00266     uint32 mem[5];
00267     char *m=(char*)mem;
00268     
00269     IPush(m, (uint16)inst);
00270     IPush(m, z);
00271     IPush(m, uint8(0));
00272     IPush(m, a);
00273     IPush(m, b);
00274     IPush(m, c);
00275     IPush(m, d);
00276     
00277     SIZECHECK
00278     append((char*)mem,INST::Desc(inst)->size);
00279 }
00280 
00281 void InstructionStorage::append(INST::IID inst,dbl a,uint8 b)
00282 {
00283     _AssertAC(inst,INST::AC_db);
00284     
00285     uint32 mem[3];
00286     char *m=(char*)mem;
00287     
00288     IPush(m, (uint16)inst);
00289     IPush(m, b);
00290     IPush(m, uint8(0));
00291     IPush(m, a);
00292     
00293     SIZECHECK
00294     append((char*)mem,INST::Desc(inst)->size);
00295 }
00296 
00297 void InstructionStorage::append(INST::IID inst,dbl a,dbl b,uint8 z)
00298 {
00299     _AssertAC(inst,INST::AC_ddb);
00300     
00301     uint32 mem[5];
00302     char *m=(char*)mem;
00303     
00304     IPush(m, (uint16)inst);
00305     IPush(m, z);
00306     IPush(m, uint8(0));
00307     IPush(m, a);
00308     IPush(m, b);
00309     
00310     SIZECHECK
00311     append((char*)mem,INST::Desc(inst)->size);
00312 }
00313 
00314 void InstructionStorage::append(INST::IID inst,dbl a,dbl b,dbl c,uint8 z)
00315 {
00316     _AssertAC(inst,INST::AC_dddb);
00317     
00318     uint32 mem[7];
00319     char *m=(char*)mem;
00320     
00321     IPush(m, (uint16)inst);
00322     IPush(m, z);
00323     IPush(m, uint8(0));
00324     IPush(m, a);
00325     IPush(m, b);
00326     IPush(m, c);
00327     
00328     SIZECHECK
00329     append((char*)mem,INST::Desc(inst)->size);
00330 }
00331 
00332 void InstructionStorage::append(INST::IID inst,dbl a,dbl b,dbl c,dbl d,uint8 z)
00333 {
00334     _AssertAC(inst,INST::AC_ddddb);
00335     
00336     uint32 mem[9];
00337     char *m=(char*)mem;
00338     
00339     IPush(m, (uint16)inst);
00340     IPush(m, z);
00341     IPush(m, uint8(0));
00342     IPush(m, a);
00343     IPush(m, b);
00344     IPush(m, c);
00345     IPush(m, d);
00346     
00347     SIZECHECK
00348     append((char*)mem,INST::Desc(inst)->size);
00349 }
00350 
00351 //------------------------------------------------------------------------------
00352 
00353 INST::IID InstructionStorage::extract(PrgAdr adr) const
00354 {
00355     INST::IID inst=InstructionAt(adr);
00356     _AssertAC(inst,INST::AC_void);
00357     
00358     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00359     
00360     SIZECHECK2
00361     return(inst);
00362 }
00363 
00364 INST::IID InstructionStorage::extract(PrgAdr adr,uint32 *a) const
00365 {
00366     INST::IID inst=InstructionAt(adr);
00367     _AssertAC(inst,INST::AC_i);
00368     
00369     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00370     
00371     IPop(m, a);
00372     
00373     SIZECHECK2
00374     return(inst);
00375 }
00376 
00377 INST::IID InstructionStorage::extract(PrgAdr adr,int32 *a) const
00378 {
00379     INST::IID inst=InstructionAt(adr);
00380     _AssertAC(inst,INST::AC_S);
00381     
00382     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00383     
00384     IPop(m, a);
00385     
00386     SIZECHECK2
00387     return(inst);
00388 }
00389 
00390 INST::IID InstructionStorage::extract(PrgAdr adr,uint8 *a,uint8 *b) const
00391 {
00392     INST::IID inst=InstructionAt(adr);
00393     _AssertAC(inst,INST::AC_bb);
00394     
00395     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00396     
00397     IPop(m, a);
00398     IPop(m, b);
00399     
00400     SIZECHECK2
00401     return(inst);
00402 }
00403 
00404 INST::IID InstructionStorage::extract(PrgAdr adr,uint16 *a,uint8 *b) const
00405 {
00406     INST::IID inst=InstructionAt(adr);
00407     _AssertAC(inst,INST::AC_sb);
00408     
00409     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00410     
00411     IPop(m, a);
00412     IPop(m, b);
00413     IPop(m, (uint8*)NULL);
00414     
00415     SIZECHECK2
00416     return(inst);
00417 }
00418 
00419 INST::IID InstructionStorage::extract(PrgAdr adr,uint32 *a,uint8 *b) const
00420 {
00421     INST::IID inst=InstructionAt(adr);
00422     _AssertAC(inst,INST::AC_ib);
00423     
00424     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00425     
00426     IPop(m, b);
00427     IPop(m, (uint8*)NULL);
00428     IPop(m, a);
00429     
00430     SIZECHECK2
00431     return(inst);
00432 }
00433 
00434 INST::IID InstructionStorage::extract(PrgAdr adr,int32 *a,uint8 *b) const
00435 {
00436     INST::IID inst=InstructionAt(adr);
00437     _AssertAC(inst,INST::AC_Sb);
00438     
00439     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00440     
00441     IPop(m, b);
00442     IPop(m, (uint8*)NULL);
00443     IPop(m, a);
00444     
00445     SIZECHECK2
00446     return(inst);
00447 }
00448 
00449 INST::IID InstructionStorage::extract(PrgAdr adr,uint64 *a,uint8 *b) const
00450 {
00451     INST::IID inst=InstructionAt(adr);
00452     _AssertAC(inst,INST::AC_lb);
00453     
00454     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00455     
00456     IPop(m, b);
00457     IPop(m, (uint8*)NULL);
00458     IPop(m, a);
00459     
00460     SIZECHECK2
00461     return(inst);
00462 }
00463 
00464 INST::IID InstructionStorage::extract(PrgAdr adr,flt *a,uint8 *b) const
00465 {
00466     INST::IID inst=InstructionAt(adr);
00467     _AssertAC(inst,INST::AC_fb);
00468     
00469     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00470     
00471     IPop(m, b);
00472     IPop(m, (uint8*)NULL);
00473     IPop(m, a);
00474     
00475     SIZECHECK2
00476     return(inst);
00477 }
00478 
00479 INST::IID InstructionStorage::extract(PrgAdr adr,flt *a,flt *b,uint8 *z) const
00480 {
00481     INST::IID inst=InstructionAt(adr);
00482     _AssertAC(inst,INST::AC_ffb);
00483     
00484     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00485     
00486     IPop(m, z);
00487     IPop(m, (uint8*)NULL);
00488     IPop(m, a);
00489     IPop(m, b);
00490     
00491     SIZECHECK2
00492     return(inst);
00493 }
00494 
00495 INST::IID InstructionStorage::extract(PrgAdr adr,flt *a,flt *b,flt *c,
00496     uint8 *z) const
00497 {
00498     INST::IID inst=InstructionAt(adr);
00499     _AssertAC(inst,INST::AC_fffb);
00500     
00501     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00502     
00503     IPop(m, z);
00504     IPop(m, (uint8*)NULL);
00505     IPop(m, a);
00506     IPop(m, b);
00507     IPop(m, c);
00508     
00509     SIZECHECK2
00510     return(inst);
00511 }
00512 
00513 INST::IID InstructionStorage::extract(PrgAdr adr,flt *a,flt *b,flt *c,flt *d,
00514     uint8 *z) const
00515 {
00516     INST::IID inst=InstructionAt(adr);
00517     _AssertAC(inst,INST::AC_ffffb);
00518     
00519     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00520     
00521     IPop(m, z);
00522     IPop(m, (uint8*)NULL);
00523     IPop(m, a);
00524     IPop(m, b);
00525     IPop(m, c);
00526     IPop(m, d);
00527     
00528     SIZECHECK2
00529     return(inst);
00530 }
00531 
00532 INST::IID InstructionStorage::extract(PrgAdr adr,dbl *a,uint8 *b) const
00533 {
00534     INST::IID inst=InstructionAt(adr);
00535     _AssertAC(inst,INST::AC_db);
00536     
00537     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00538     
00539     IPop(m, b);
00540     IPop(m, (uint8*)NULL);
00541     IPop(m, a);
00542     
00543     SIZECHECK2
00544     return(inst);
00545 }
00546 
00547 INST::IID InstructionStorage::extract(PrgAdr adr,dbl *a,dbl *b,uint8 *z) const
00548 {
00549     INST::IID inst=InstructionAt(adr);
00550     _AssertAC(inst,INST::AC_ddb);
00551     
00552     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00553     
00554     IPop(m, z);
00555     IPop(m, (uint8*)NULL);
00556     IPop(m, a);
00557     IPop(m, b);
00558     
00559     SIZECHECK2
00560     return(inst);
00561 }
00562 
00563 INST::IID InstructionStorage::extract(PrgAdr adr,dbl *a,dbl *b,dbl *c,
00564     uint8 *z) const
00565 {
00566     INST::IID inst=InstructionAt(adr);
00567     _AssertAC(inst,INST::AC_dddb);
00568     
00569     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00570     
00571     IPop(m, z);
00572     IPop(m, (uint8*)NULL);
00573     IPop(m, a);
00574     IPop(m, b);
00575     IPop(m, c);
00576     
00577     SIZECHECK2
00578     return(inst);
00579 }
00580 
00581 INST::IID InstructionStorage::extract(PrgAdr adr,dbl *a,dbl *b,dbl *c,
00582     dbl *d,uint8 *z) const
00583 {
00584     INST::IID inst=InstructionAt(adr);
00585     _AssertAC(inst,INST::AC_ddddb);
00586     
00587     const char *mem=&prg[adr],*m=mem+2;   // +2 -> skip instruction
00588     
00589     IPop(m, z);
00590     IPop(m, (uint8*)NULL);
00591     IPop(m, a);
00592     IPop(m, b);
00593     IPop(m, c);
00594     IPop(m, d);
00595     
00596     SIZECHECK2
00597     return(inst);
00598 }
00599 
00600 }  // end of namespace VM

Generated on Sat Feb 19 22:33:47 2005 for Ray by doxygen 1.3.5