00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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
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
00079 Assert(0);
00080 }
00081
00082
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
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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 }