00001 #define sign_extend(N,SIZE) (((int)((N) << (sizeof(unsigned)*8-(SIZE)))) >> (sizeof(unsigned)*8-(SIZE)))
00002 #include <assert.h>
00003
00004 #line 1 "frontend/machine/st20/decoder.m"
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <assert.h>
00025
00026 #include "rtl.h"
00027 #include "decoder.h"
00028 #include "st20decoder.h"
00029 #include "exp.h"
00030 #include "proc.h"
00031 #include "boomerang.h"
00032 #include "statement.h"
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 void ST20Decoder::unused(int x)
00045 {}
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 static DecodeResult result;
00058 DecodeResult& ST20Decoder::decodeInstruction (ADDRESS pc, int delta) {
00059 result.reset();
00060 ADDRESS hostPC = pc + delta;
00061 std::list<Statement*>* stmts = NULL;
00062 unsigned total = 0;
00063
00064 while (1) {
00065
00066
00067 #line 60 "frontend/machine/st20/decoder.m"
00068 {
00069 dword MATCH_p =
00070
00071 #line 60 "frontend/machine/st20/decoder.m"
00072 hostPC+result.numBytes++
00073 ;
00074 char *MATCH_name;
00075 static char *MATCH_name_fc_0[] = {
00076 (char *)0, "ldlp", (char *)0, "ldnl", "ldc", "ldnlp", (char *)0, "ldl",
00077 "adc", (char *)0, (char *)0, "ajw", "eqc", "stl", "stnl",
00078 };
00079 unsigned MATCH_w_8_0;
00080 {
00081 MATCH_w_8_0 = getByte(MATCH_p);
00082
00083 switch((MATCH_w_8_0 >> 4 & 0xf) ) {
00084 case 0:
00085 {
00086 unsigned oper = (MATCH_w_8_0 & 0xf) ;
00087
00088 #line 74 "frontend/machine/st20/decoder.m"
00089
00090
00091 unconditionalJump("j", result.numBytes, hostPC+result.numBytes+total+oper, delta, pc, stmts, result);
00092
00093
00094
00095
00096
00097
00098 }
00099
00100 break;
00101 case 1: case 3: case 4: case 5: case 7: case 8: case 11: case 12:
00102 case 13: case 14:
00103 MATCH_name =
00104 MATCH_name_fc_0[(MATCH_w_8_0 >> 4 & 0xf) ];
00105 {
00106 char *name = MATCH_name;
00107 unsigned oper = (MATCH_w_8_0 & 0xf) ;
00108
00109 #line 71 "frontend/machine/st20/decoder.m"
00110
00111
00112 stmts = instantiate(pc, name, new Const(total+oper));
00113
00114
00115
00116
00117
00118
00119 }
00120
00121 break;
00122 case 2:
00123 {
00124 unsigned oper = (MATCH_w_8_0 & 0xf) ;
00125
00126 #line 63 "frontend/machine/st20/decoder.m"
00127
00128
00129 total = (total + oper) << 4;
00130
00131 continue;
00132
00133
00134
00135
00136
00137
00138 }
00139
00140 break;
00141 case 6:
00142 {
00143 unsigned oper = (MATCH_w_8_0 & 0xf) ;
00144
00145 #line 67 "frontend/machine/st20/decoder.m"
00146
00147
00148 total = (total + ~oper) << 4;
00149
00150 continue;
00151
00152
00153
00154
00155
00156
00157 }
00158
00159 break;
00160 case 9:
00161 {
00162 unsigned oper = (MATCH_w_8_0 & 0xf) ;
00163
00164 #line 77 "frontend/machine/st20/decoder.m"
00165
00166
00167 total += oper;
00168
00169 stmts = instantiate(pc, "call" , new Const(total));
00170
00171 CallStatement* newCall = new CallStatement;
00172
00173 newCall->setIsComputed(false);
00174
00175 newCall->setDest(pc+result.numBytes+total);
00176
00177 result.rtl = new RTL(pc, stmts);
00178
00179 result.rtl->appendStmt(newCall);
00180
00181
00182
00183
00184
00185
00186 }
00187
00188 break;
00189 case 10:
00190 {
00191 unsigned oper = (MATCH_w_8_0 & 0xf) ;
00192
00193 #line 86 "frontend/machine/st20/decoder.m"
00194
00195
00196 BranchStatement* br = new BranchStatement();
00197
00198
00199
00200 br->setDest(pc+result.numBytes+total+oper);
00201
00202
00203
00204 br->setCondExpr(new Binary(opEquals,dis_Reg(0),new Const(0)));
00205
00206 result.rtl = new RTL(pc, stmts);
00207
00208 result.rtl->appendStmt(br);
00209
00210
00211
00212
00213
00214
00215 }
00216
00217 break;
00218 case 15:
00219 {
00220 unsigned oper = (MATCH_w_8_0 & 0xf) ;
00221
00222 #line 95 "frontend/machine/st20/decoder.m"
00223
00224
00225 total |= oper;
00226
00227 char* name = NULL;
00228
00229 bool isRet = false;
00230
00231 if (total >= 0) {
00232
00233 switch (total) {
00234
00235 case 0x00: name = "rev"; break;
00236
00237 case 0x01: name = "lb"; break;
00238
00239 case 0x02: name = "bsub"; break;
00240
00241 case 0x03: name = "endp"; break;
00242
00243 case 0x04: name = "diff"; break;
00244
00245 case 0x05: name = "add"; break;
00246
00247 case 0x06: name = "gcall"; break;
00248
00249 case 0x07: name = "in"; break;
00250
00251 case 0x08: name = "prod"; break;
00252
00253 case 0x09: name = "gt"; break;
00254
00255 case 0x0A: name = "wsub"; break;
00256
00257 case 0x0B: name = "out"; break;
00258
00259 case 0x0C: name = "sub"; break;
00260
00261 case 0x0D: name = "startp"; break;
00262
00263 case 0x0E: name = "outbyte";break;
00264
00265 case 0x0F: name = "outword";break;
00266
00267 case 0x10: name = "seterr"; break;
00268
00269 case 0x12: name = "resetch";break;
00270
00271 case 0x13: name = "csub0"; break;
00272
00273 case 0x15: name = "stopp"; break;
00274
00275 case 0x16: name = "ladd"; break;
00276
00277 case 0x17: name = "stlb"; break;
00278
00279 case 0x18: name = "sthf"; break;
00280
00281 case 0x19: name = "norm"; break;
00282
00283 case 0x1A: name = "ldiv"; break;
00284
00285 case 0x1B: name = "ldpi"; break;
00286
00287 case 0x1C: name = "stlf"; break;
00288
00289 case 0x1D: name = "xdble"; break;
00290
00291 case 0x1E: name = "ldpri"; break;
00292
00293 case 0x1F: name = "rem"; break;
00294
00295 case 0x20: name = "ret"; isRet = true; break;
00296
00297 case 0x21: name = "lend"; break;
00298
00299 case 0x22: name = "ldtimer";break;
00300
00301 case 0x29: name = "testerr";break;
00302
00303 case 0x2A: name = "testpranal";break;
00304
00305 case 0x2B: name = "tin"; break;
00306
00307 case 0x2C: name = "div"; break;
00308
00309 case 0x2E: name = "dist"; break;
00310
00311 case 0x2F: name = "disc"; break;
00312
00313 case 0x30: name = "diss"; break;
00314
00315 case 0x31: name = "lmul"; break;
00316
00317 case 0x32: name = "not"; break;
00318
00319 case 0x33: name = "xor"; break;
00320
00321 case 0x34: name = "bcnt"; break;
00322
00323 case 0x35: name = "lshr"; break;
00324
00325 case 0x36: name = "lshl"; break;
00326
00327 case 0x37: name = "lsum"; break;
00328
00329 case 0x38: name = "lsub"; break;
00330
00331 case 0x39: name = "runp"; break;
00332
00333 case 0x3A: name = "xword"; break;
00334
00335 case 0x3B: name = "sb"; break;
00336
00337 case 0x3C: name = "gajw"; break;
00338
00339 case 0x3D: name = "savel"; break;
00340
00341 case 0x3E: name = "saveh"; break;
00342
00343 case 0x3F: name = "wcnt"; break;
00344
00345 case 0x40: name = "shr"; break;
00346
00347 case 0x41: name = "shl"; break;
00348
00349 case 0x42: name = "mint"; break;
00350
00351 case 0x43: name = "alt"; break;
00352
00353 case 0x44: name = "altwt"; break;
00354
00355 case 0x45: name = "altend"; break;
00356
00357 case 0x46: name = "and"; break;
00358
00359 case 0x47: name = "enbt"; break;
00360
00361 case 0x48: name = "enbc"; break;
00362
00363 case 0x49: name = "enbs"; break;
00364
00365 case 0x4A: name = "move"; break;
00366
00367 case 0x4B: name = "or"; break;
00368
00369 case 0x4C: name = "csngl"; break;
00370
00371 case 0x4D: name = "ccnt1"; break;
00372
00373 case 0x4E: name = "talt"; break;
00374
00375 case 0x4F: name = "ldiff"; break;
00376
00377 case 0x50: name = "sthb"; break;
00378
00379 case 0x51: name = "taltwt"; break;
00380
00381 case 0x52: name = "sum"; break;
00382
00383 case 0x53: name = "mul"; break;
00384
00385 case 0x54: name = "sttimer";break;
00386
00387 case 0x55: name = "stoperr";break;
00388
00389 case 0x56: name = "cword"; break;
00390
00391 case 0x57: name = "clrhalterr"; break;
00392
00393 case 0x58: name = "sethalterr"; break;
00394
00395 case 0x59: name = "testhalterr";break;
00396
00397 case 0x5A: name = "dup"; break;
00398
00399 case 0x5B: name = "move2dinit"; break;
00400
00401 case 0x5C: name = "move2dall"; break;
00402
00403 case 0x5D: name = "move2dnonzero";break;
00404
00405 case 0x5E: name = "move2dzero"; break;
00406
00407 case 0x5F: name = "gtu"; break;
00408
00409 case 0x63: name = "unpacksn"; break;
00410
00411 case 0x64: name = "slmul"; break;
00412
00413 case 0x65: name = "sulmul"; break;
00414
00415 case 0x68: name = "satadd"; break;
00416
00417 case 0x69: name = "satsub"; break;
00418
00419 case 0x6A: name = "satmul"; break;
00420
00421 case 0x6C: name = "postnormsn"; break;
00422
00423 case 0x6D: name = "roundsn"; break;
00424
00425 case 0x6E: name = "ldtraph"; break;
00426
00427 case 0x6F: name = "sttraph"; break;
00428
00429 case 0x71: name = "ldinf"; break;
00430
00431 case 0x72: name = "fmul"; break;
00432
00433 case 0x73: name = "cflerr"; break;
00434
00435 case 0x74: name = "crcword"; break;
00436
00437 case 0x75: name = "crcbyte"; break;
00438
00439 case 0x76: name = "bitcnt"; break;
00440
00441 case 0x77: name = "bitrevword"; break;
00442
00443 case 0x78: name = "bitrevnbits";break;
00444
00445 case 0x79: name = "pop"; break;
00446
00447 case 0x7E: name = "ldmemstartval";break;
00448
00449 case 0x81: name = "wsubdb"; break;
00450
00451 case 0x9C: name = "fptesterr"; break;
00452
00453 case 0xB0: name = "settimeslice";break;
00454
00455 case 0xB8: name = "xbword"; break;
00456
00457 case 0xB9: name = "lbx"; break;
00458
00459 case 0xBA: name = "cb"; break;
00460
00461 case 0xBB: name = "cbu"; break;
00462
00463 case 0xC1: name = "ssub"; break;
00464
00465 case 0xC4: name = "intdis"; break;
00466
00467 case 0xC5: name = "intenb"; break;
00468
00469 case 0xC6: name = "ldtrapped"; break;
00470
00471 case 0xC7: name = "cir"; break;
00472
00473 case 0xC8: name = "ss"; break;
00474
00475 case 0xCA: name = "ls"; break;
00476
00477 case 0xCB: name = "sttrapped"; break;
00478
00479 case 0xCC: name = "ciru"; break;
00480
00481 case 0xCD: name = "gintdis"; break;
00482
00483 case 0xCE: name = "gintenb"; break;
00484
00485 case 0xF0: name = "devlb"; break;
00486
00487 case 0xF1: name = "devsb"; break;
00488
00489 case 0xF2: name = "devls"; break;
00490
00491 case 0xF3: name = "devss"; break;
00492
00493 case 0xF4: name = "devlw"; break;
00494
00495 case 0xF5: name = "devsw"; break;
00496
00497 case 0xF6: name = "null"; break;
00498
00499 case 0xF7: name = "null"; break;
00500
00501 case 0xF8: name = "xsword"; break;
00502
00503 case 0xF9: name = "lsx"; break;
00504
00505 case 0xFA: name = "cs"; break;
00506
00507 case 0xFB: name = "csu"; break;
00508
00509 case 0x17C:name = "lddevid"; break;
00510
00511 }
00512
00513 } else {
00514
00515
00516
00517 total = (~total & ~0xF) | (total & 0xF);
00518
00519 switch (total) {
00520
00521 case 0x00: name = "swapqueue"; break;
00522
00523 case 0x01: name = "swaptimer"; break;
00524
00525 case 0x02: name = "insertqueue";break;
00526
00527 case 0x03: name = "timeslice"; break;
00528
00529 case 0x04: name = "signal"; break;
00530
00531 case 0x05: name = "wait"; break;
00532
00533 case 0x06: name = "trapdis"; break;
00534
00535 case 0x07: name = "trapenb"; break;
00536
00537 case 0x0B: name = "tret"; isRet = true; break;
00538
00539 case 0x0C: name = "ldshadow"; break;
00540
00541 case 0x0D: name = "stshadow"; break;
00542
00543 case 0x1F: name = "iret"; isRet = true; break;
00544
00545 case 0x24: name = "devmove"; break;
00546
00547 case 0x2E: name = "restart"; break;
00548
00549 case 0x2F: name = "causeerror"; break;
00550
00551 case 0x30: name = "nop"; break;
00552
00553 case 0x4C: name = "stclock"; break;
00554
00555 case 0x4D: name = "ldclock"; break;
00556
00557 case 0x4E: name = "clockdis"; break;
00558
00559 case 0x4F: name = "clockenb"; break;
00560
00561 case 0x8C: name = "ldprodid"; break;
00562
00563 case 0x8D: name = "reboot"; break;
00564
00565 }
00566
00567 }
00568
00569 if (name) {
00570
00571 stmts = instantiate(pc, name);
00572
00573 if (isRet) {
00574
00575 result.rtl = new RTL(pc, stmts);
00576
00577 result.rtl->appendStmt(new ReturnStatement);
00578
00579 }
00580
00581 } else {
00582
00583 result.valid = false;
00584
00585 result.rtl = NULL;
00586
00587 result.numBytes = 0;
00588
00589 return result;
00590
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600 }
00601
00602 break;
00603 default: assert(0);
00604 }
00605
00606 }goto MATCH_finished_a;
00607
00608 MATCH_finished_a: (void)0;
00609
00610 }
00611
00612 #line 283 "frontend/machine/st20/decoder.m"
00613 break;
00614 }
00615
00616 if (result.rtl == 0)
00617 result.rtl = new RTL(pc, stmts);
00618 return result;
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 Byte ST20Decoder::getByte (unsigned lc)
00636
00637 {
00638 return *(Byte *)lc;
00639 }
00640
00641
00642
00643
00644
00645
00646
00647 SWord ST20Decoder::getWord (unsigned lc)
00648
00649 {
00650 return (SWord)(*(Byte *)lc + (*(Byte *)(lc+1) << 8));
00651 }
00652
00653
00654
00655
00656
00657
00658
00659 DWord ST20Decoder::getDword (unsigned lc)
00660
00661 {
00662 return (DWord)(*(Byte *)lc + (*(Byte *)(lc+1) << 8) +
00663 (*(Byte *)(lc+2) << 16) + (*(Byte *)(lc+3) << 24));
00664 }
00665
00666
00667
00668
00669
00670
00671
00672
00673 ST20Decoder::ST20Decoder() : NJMCDecoder(prog)
00674 {
00675 std::string file = Boomerang::get()->getProgPath() + "frontend/machine/st20/st20.ssl";
00676 RTLDict.readSSLFile(file.c_str());
00677 }
00678
00679
00680 int ST20Decoder::decodeAssemblyInstruction(unsigned, int)
00681 { return 0; }
00682
00683
00684