00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <assert.h>
00021
00022 #include "rtl.h"
00023 #include "decoder.h"
00024 #include "st20decoder.h"
00025 #include "exp.h"
00026 #include "proc.h"
00027 #include "boomerang.h"
00028 #include "statement.h"
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 void ST20Decoder::unused(int x)
00041 {}
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 static DecodeResult result;
00054 DecodeResult& ST20Decoder::decodeInstruction (ADDRESS pc, int delta) {
00055 result.reset();
00056 ADDRESS hostPC = pc + delta;
00057 std::list<Statement*>* stmts = NULL;
00058 unsigned total = 0;
00059
00060 while (1) {
00061 match hostPC+result.numBytes++ to
00062
00063 | pfix(oper) =>
00064 total = (total + oper) << 4;
00065 continue;
00066
00067 | nfix(oper) =>
00068 total = (total + ~oper) << 4;
00069 continue;
00070
00071 | primary(oper) =>
00072 stmts = instantiate(pc, name, new Const(total+oper));
00073
00074 | j (oper) =>
00075 unconditionalJump("j", result.numBytes, hostPC+result.numBytes+total+oper, delta, pc, stmts, result);
00076
00077 | call (oper) =>
00078 total += oper;
00079 stmts = instantiate(pc, "call" , new Const(total));
00080 CallStatement* newCall = new CallStatement;
00081 newCall->setIsComputed(false);
00082 newCall->setDest(pc+result.numBytes+total);
00083 result.rtl = new RTL(pc, stmts);
00084 result.rtl->appendStmt(newCall);
00085
00086 | cj (oper) =>
00087 BranchStatement* br = new BranchStatement();
00088
00089 br->setDest(pc+result.numBytes+total+oper);
00090
00091 br->setCondExpr(new Binary(opEquals,dis_Reg(0),new Const(0)));
00092 result.rtl = new RTL(pc, stmts);
00093 result.rtl->appendStmt(br);
00094
00095 | opr (oper) =>
00096 total |= oper;
00097 char* name = NULL;
00098 bool isRet = false;
00099 if (total >= 0) {
00100 switch (total) {
00101 case 0x00: name = "rev"; break;
00102 case 0x01: name = "lb"; break;
00103 case 0x02: name = "bsub"; break;
00104 case 0x03: name = "endp"; break;
00105 case 0x04: name = "diff"; break;
00106 case 0x05: name = "add"; break;
00107 case 0x06: name = "gcall"; break;
00108 case 0x07: name = "in"; break;
00109 case 0x08: name = "prod"; break;
00110 case 0x09: name = "gt"; break;
00111 case 0x0A: name = "wsub"; break;
00112 case 0x0B: name = "out"; break;
00113 case 0x0C: name = "sub"; break;
00114 case 0x0D: name = "startp"; break;
00115 case 0x0E: name = "outbyte";break;
00116 case 0x0F: name = "outword";break;
00117 case 0x10: name = "seterr"; break;
00118 case 0x12: name = "resetch";break;
00119 case 0x13: name = "csub0"; break;
00120 case 0x15: name = "stopp"; break;
00121 case 0x16: name = "ladd"; break;
00122 case 0x17: name = "stlb"; break;
00123 case 0x18: name = "sthf"; break;
00124 case 0x19: name = "norm"; break;
00125 case 0x1A: name = "ldiv"; break;
00126 case 0x1B: name = "ldpi"; break;
00127 case 0x1C: name = "stlf"; break;
00128 case 0x1D: name = "xdble"; break;
00129 case 0x1E: name = "ldpri"; break;
00130 case 0x1F: name = "rem"; break;
00131 case 0x20: name = "ret"; isRet = true; break;
00132 case 0x21: name = "lend"; break;
00133 case 0x22: name = "ldtimer";break;
00134 case 0x29: name = "testerr";break;
00135 case 0x2A: name = "testpranal";break;
00136 case 0x2B: name = "tin"; break;
00137 case 0x2C: name = "div"; break;
00138 case 0x2E: name = "dist"; break;
00139 case 0x2F: name = "disc"; break;
00140 case 0x30: name = "diss"; break;
00141 case 0x31: name = "lmul"; break;
00142 case 0x32: name = "not"; break;
00143 case 0x33: name = "xor"; break;
00144 case 0x34: name = "bcnt"; break;
00145 case 0x35: name = "lshr"; break;
00146 case 0x36: name = "lshl"; break;
00147 case 0x37: name = "lsum"; break;
00148 case 0x38: name = "lsub"; break;
00149 case 0x39: name = "runp"; break;
00150 case 0x3A: name = "xword"; break;
00151 case 0x3B: name = "sb"; break;
00152 case 0x3C: name = "gajw"; break;
00153 case 0x3D: name = "savel"; break;
00154 case 0x3E: name = "saveh"; break;
00155 case 0x3F: name = "wcnt"; break;
00156 case 0x40: name = "shr"; break;
00157 case 0x41: name = "shl"; break;
00158 case 0x42: name = "mint"; break;
00159 case 0x43: name = "alt"; break;
00160 case 0x44: name = "altwt"; break;
00161 case 0x45: name = "altend"; break;
00162 case 0x46: name = "and"; break;
00163 case 0x47: name = "enbt"; break;
00164 case 0x48: name = "enbc"; break;
00165 case 0x49: name = "enbs"; break;
00166 case 0x4A: name = "move"; break;
00167 case 0x4B: name = "or"; break;
00168 case 0x4C: name = "csngl"; break;
00169 case 0x4D: name = "ccnt1"; break;
00170 case 0x4E: name = "talt"; break;
00171 case 0x4F: name = "ldiff"; break;
00172 case 0x50: name = "sthb"; break;
00173 case 0x51: name = "taltwt"; break;
00174 case 0x52: name = "sum"; break;
00175 case 0x53: name = "mul"; break;
00176 case 0x54: name = "sttimer";break;
00177 case 0x55: name = "stoperr";break;
00178 case 0x56: name = "cword"; break;
00179 case 0x57: name = "clrhalterr"; break;
00180 case 0x58: name = "sethalterr"; break;
00181 case 0x59: name = "testhalterr";break;
00182 case 0x5A: name = "dup"; break;
00183 case 0x5B: name = "move2dinit"; break;
00184 case 0x5C: name = "move2dall"; break;
00185 case 0x5D: name = "move2dnonzero";break;
00186 case 0x5E: name = "move2dzero"; break;
00187 case 0x5F: name = "gtu"; break;
00188 case 0x63: name = "unpacksn"; break;
00189 case 0x64: name = "slmul"; break;
00190 case 0x65: name = "sulmul"; break;
00191 case 0x68: name = "satadd"; break;
00192 case 0x69: name = "satsub"; break;
00193 case 0x6A: name = "satmul"; break;
00194 case 0x6C: name = "postnormsn"; break;
00195 case 0x6D: name = "roundsn"; break;
00196 case 0x6E: name = "ldtraph"; break;
00197 case 0x6F: name = "sttraph"; break;
00198 case 0x71: name = "ldinf"; break;
00199 case 0x72: name = "fmul"; break;
00200 case 0x73: name = "cflerr"; break;
00201 case 0x74: name = "crcword"; break;
00202 case 0x75: name = "crcbyte"; break;
00203 case 0x76: name = "bitcnt"; break;
00204 case 0x77: name = "bitrevword"; break;
00205 case 0x78: name = "bitrevnbits";break;
00206 case 0x79: name = "pop"; break;
00207 case 0x7E: name = "ldmemstartval";break;
00208 case 0x81: name = "wsubdb"; break;
00209 case 0x9C: name = "fptesterr"; break;
00210 case 0xB0: name = "settimeslice";break;
00211 case 0xB8: name = "xbword"; break;
00212 case 0xB9: name = "lbx"; break;
00213 case 0xBA: name = "cb"; break;
00214 case 0xBB: name = "cbu"; break;
00215 case 0xC1: name = "ssub"; break;
00216 case 0xC4: name = "intdis"; break;
00217 case 0xC5: name = "intenb"; break;
00218 case 0xC6: name = "ldtrapped"; break;
00219 case 0xC7: name = "cir"; break;
00220 case 0xC8: name = "ss"; break;
00221 case 0xCA: name = "ls"; break;
00222 case 0xCB: name = "sttrapped"; break;
00223 case 0xCC: name = "ciru"; break;
00224 case 0xCD: name = "gintdis"; break;
00225 case 0xCE: name = "gintenb"; break;
00226 case 0xF0: name = "devlb"; break;
00227 case 0xF1: name = "devsb"; break;
00228 case 0xF2: name = "devls"; break;
00229 case 0xF3: name = "devss"; break;
00230 case 0xF4: name = "devlw"; break;
00231 case 0xF5: name = "devsw"; break;
00232 case 0xF6: name = "null"; break;
00233 case 0xF7: name = "null"; break;
00234 case 0xF8: name = "xsword"; break;
00235 case 0xF9: name = "lsx"; break;
00236 case 0xFA: name = "cs"; break;
00237 case 0xFB: name = "csu"; break;
00238 case 0x17C:name = "lddevid"; break;
00239 }
00240 } else {
00241
00242 total = (~total & ~0xF) | (total & 0xF);
00243 switch (total) {
00244 case 0x00: name = "swapqueue"; break;
00245 case 0x01: name = "swaptimer"; break;
00246 case 0x02: name = "insertqueue";break;
00247 case 0x03: name = "timeslice"; break;
00248 case 0x04: name = "signal"; break;
00249 case 0x05: name = "wait"; break;
00250 case 0x06: name = "trapdis"; break;
00251 case 0x07: name = "trapenb"; break;
00252 case 0x0B: name = "tret"; isRet = true; break;
00253 case 0x0C: name = "ldshadow"; break;
00254 case 0x0D: name = "stshadow"; break;
00255 case 0x1F: name = "iret"; isRet = true; break;
00256 case 0x24: name = "devmove"; break;
00257 case 0x2E: name = "restart"; break;
00258 case 0x2F: name = "causeerror"; break;
00259 case 0x30: name = "nop"; break;
00260 case 0x4C: name = "stclock"; break;
00261 case 0x4D: name = "ldclock"; break;
00262 case 0x4E: name = "clockdis"; break;
00263 case 0x4F: name = "clockenb"; break;
00264 case 0x8C: name = "ldprodid"; break;
00265 case 0x8D: name = "reboot"; break;
00266 }
00267 }
00268 if (name) {
00269 stmts = instantiate(pc, name);
00270 if (isRet) {
00271 result.rtl = new RTL(pc, stmts);
00272 result.rtl->appendStmt(new ReturnStatement);
00273 }
00274 } else {
00275 result.valid = false;
00276 result.rtl = NULL;
00277 result.numBytes = 0;
00278 return result;
00279 }
00280
00281
00282 endmatch
00283 break;
00284 }
00285
00286 if (result.rtl == 0)
00287 result.rtl = new RTL(pc, stmts);
00288 return result;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 Byte ST20Decoder::getByte (unsigned lc)
00306
00307 {
00308 return *(Byte *)lc;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317 SWord ST20Decoder::getWord (unsigned lc)
00318
00319 {
00320 return (SWord)(*(Byte *)lc + (*(Byte *)(lc+1) << 8));
00321 }
00322
00323
00324
00325
00326
00327
00328
00329 DWord ST20Decoder::getDword (unsigned lc)
00330
00331 {
00332 return (DWord)(*(Byte *)lc + (*(Byte *)(lc+1) << 8) +
00333 (*(Byte *)(lc+2) << 16) + (*(Byte *)(lc+3) << 24));
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343 ST20Decoder::ST20Decoder() : NJMCDecoder(prog)
00344 {
00345 std::string file = Boomerang::get()->getProgPath() + "frontend/machine/st20/st20.ssl";
00346 RTLDict.readSSLFile(file.c_str());
00347 }
00348
00349
00350 int ST20Decoder::decodeAssemblyInstruction(unsigned, int)
00351 { return 0; }
00352