00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00028
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <stdlib.h>
00038 #include "ac_decoder.h"
00039
00040
00042 int ExpandInstrBuffer(int index);
00043
00044
00045 unsigned long long GetBits(unsigned char *buffer, int *quant, int last, int quantity, int sign)
00046 {
00048 #define BUFFER(index) ((index<*quant) ? (buffer[index]) : (*quant=ExpandInstrBuffer(index),buffer[index]))
00049
00050 int first = last - (quantity-1);
00051 int index;
00052 unsigned long long value;
00053
00054
00055 index = first/8; first %= 8;
00056 value = BUFFER(index);
00057
00058
00059 value &= 0xFF >> first;
00060
00061
00062 last = first + (quantity-1);
00063
00064
00065 if (last < 8) {
00066
00067
00068 value >>= 8 - (last+1);
00069 }
00070
00071
00072 else {
00073
00074
00075 index++;
00076 last -= 8;
00077
00078
00079 while (last >= 8) {
00080 value <<= 8;
00081 value |= BUFFER(index);
00082
00083
00084 index++;
00085 last -= 8;
00086 }
00087
00088
00089 value <<= last+1;
00090 value |= BUFFER(index) >> (8 - (last+1));
00091 }
00092
00093
00094 if (sign && ( value >= (1 << (quantity-1)) ))
00095 value |= (~0LL) << quantity;
00096
00097 return value;
00098 #undef BUFFER
00099 }
00100
00101
00106 char *NewString(const char *s)
00107 {
00108 char *returnValue = (char *) malloc(strlen(s) + 1);
00109 strcpy(returnValue, s);
00110
00111 return returnValue;
00112 }
00113
00114
00115 void ShowDecField(ac_dec_field *f)
00116 {
00117 while (f) {
00118 printf("\tac_dec_field\n\t Name : %s\n\t Size : %d\n\t First: %d\n\t ID : %d\n\t Value: %ld\n",
00119 f -> name, f -> size, f -> first_bit, f -> id, f -> val);
00120 f = f -> next;
00121 }
00122 }
00123
00124
00125 void ShowDecFormat(ac_dec_format *f)
00126 {
00127 while (f) {
00128 printf("ac_dec_format\nName: %s\nFields:\n", f -> name);
00129 ShowDecField(f -> fields);
00130 f = f -> next;
00131 }
00132 }
00133
00134
00135 void ShowDecodeList(ac_dec_list *l)
00136 {
00137 while (l) {
00138 printf("\tac_dec_list\n\t Name : %s\n\t Value: %d\n", l -> name, l -> value);
00139 l = l -> next;
00140 }
00141 }
00142
00143
00144 void ShowDecInstr(ac_dec_instr *i)
00145 {
00146 while (i) {
00147 printf("ac_dec_instr\nName : %s\nMnemonic: %s\nASM : %s\nFormat : %s\nDecode List:\n",
00148 i -> name, i -> mnemonic, i -> asm_str, i -> format);
00149 ShowDecodeList(i -> dec_list);
00150 i = i -> next;
00151 }
00152 }
00153
00154
00155 void ShowDecoder(ac_decoder *d, unsigned level)
00156 {
00157 char *ident = (char *) malloc(level * 4 + 1);
00158 unsigned counter;
00159
00160 for (counter = 0; counter < level * 4; counter ++)
00161 ident[counter] = ' ';
00162
00163 ident[level * 4] = '\0';
00164
00165 while (d) {
00166 printf("%sac_decoder:\n", ident);
00167 printf("%s Field:\n", ident);
00168 printf("%s Name: %s\n%s Val : %d\n", ident, d -> check -> name, ident, d -> check -> value);
00169 if (d -> found) {
00170 printf("%s Instruction Found:\n", ident);
00171 printf("%s Name : %s\n%s Mnemonic: %s\n", ident, d -> found -> name, ident, d -> found -> mnemonic);
00172 }
00173 else
00174 ShowDecoder(d -> subcheck, level + 1);
00175
00176 d = d -> next;
00177 }
00178
00179 free(ident);
00180 }
00181
00182
00183 void MemoryError(char *fileName, long lineNumber, char *functionName)
00184 {
00185 fprintf(stderr, "%s: %ld: Not enough memory at %s", fileName, lineNumber, functionName);
00186 exit(1);
00187 }
00188
00189
00190 void ShowError(char *msg)
00191 {
00192 fprintf(stderr, msg);
00193 exit(1);
00194 }
00195
00196
00198 int CompareFields(const void *p1, const void *p2)
00199 {
00200 const ac_dec_field *f1 = (const ac_dec_field *) p1, *f2 = (const ac_dec_field *) p2;
00201
00202 return strcmp(f1 -> name, f2 -> name);
00203 }
00204
00205
00206
00207
00208
00209
00210 int CheckFields(const ac_dec_field *f1, const ac_dec_field *f2)
00211 {
00212 if (!strcmp(f1 -> name, f2 -> name)) {
00213 if (strcmp(f1 -> name, "0")) {
00214 if ((f1 -> size != f2 -> size) || (f1 -> first_bit != f2 -> first_bit)) {
00215 ShowError("Fields with the same name should have the same position.\n");
00216 return 0;
00217 }
00218 }
00219 else
00220 return 1;
00221
00222 return -1;
00223 }
00224 return 1;
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 void FreeDecField(ac_dec_field *f)
00245 {
00246 free(f -> name);
00247 free(f);
00248 }
00249
00250
00251 ac_dec_field *FindDecField(ac_dec_field *fields, char *name)
00252 {
00253 while (fields) {
00254 if (!strcmp(fields -> name, name))
00255 return fields;
00256
00257 fields = fields -> next;
00258 }
00259
00260 return NULL;
00261 }
00262
00263
00264 ac_dec_field *PutIDs(ac_dec_format *formats, unsigned nFields)
00265
00266
00267
00268
00269
00270 {
00271 ac_dec_field *fields, *tmp;
00272 ac_dec_format *f = formats;
00273 unsigned limit = 0, index, result;
00274 char found;
00275
00276
00277 fields = (ac_dec_field *) malloc(nFields * sizeof(ac_dec_field));
00278
00279
00280 while (f) {
00281 tmp = f -> fields;
00282 while (tmp) {
00283 found = 0;
00284 for (index = 0; index < limit; index ++) {
00285 result = CheckFields(&(fields[index]), tmp);
00286 if (result == -1) {
00287 found = 1;
00288 tmp -> id = fields[index].id;
00289 break;
00290 }
00291 }
00292
00293 if (!found) {
00294 tmp -> id = limit + 1;
00295 fields[limit] = *tmp;
00296 fields[limit].name = NewString(tmp -> name);
00297
00298 if (limit != 0)
00299 fields[limit - 1].next = &(fields[limit]);
00300
00301 fields[limit++].next = NULL;
00302 }
00303
00304 tmp = tmp -> next;
00305 }
00306 f = f -> next;
00307 }
00308
00309 return fields;
00310 }
00311
00312
00313 ac_decoder *AddToDecoder(ac_decoder *decoder, ac_dec_instr *instruction, ac_dec_field *fields)
00314 {
00315 ac_decoder *d = decoder, *base = decoder;
00316
00317 ac_dec_list *l = instruction -> dec_list;
00318
00319
00320 if (l == NULL) {
00321 fprintf(stderr, "Error: Instruction %s doesn't have a decode list.\n", instruction -> name);
00322 exit(1);
00323 }
00324
00325 if (d == NULL) {
00326 base = d = (ac_decoder *) malloc(sizeof(ac_decoder));
00327 d -> check = (ac_dec_list *) malloc(sizeof(ac_dec_list));
00328 d -> check -> name = NewString(l -> name);
00329 d -> check -> value = l -> value;
00330 d -> found = NULL;
00331 d -> subcheck = NULL;
00332 d -> next = NULL;
00333 }
00334
00335 while (l) {
00336
00337 if ((!strcmp(d -> check -> name, l -> name)) && (d -> check -> value == l -> value))
00338 if (l -> next == NULL) {
00339 d -> found = instruction;
00340 l = l -> next;
00341 }
00342 else {
00343 l = l -> next;
00344 if (d -> subcheck != NULL)
00345 d = d -> subcheck;
00346 else {
00347 d -> subcheck = (ac_decoder *) malloc(sizeof(ac_decoder));
00348 d = d -> subcheck;
00349 d -> check = (ac_dec_list *) malloc(sizeof(ac_dec_list));
00350 d -> check -> name = NewString(l -> name);
00351 d -> check -> value = l -> value;
00352 d -> found = NULL;
00353 d -> subcheck = NULL;
00354 d -> next = NULL;
00355 }
00356 }
00357 else {
00358 if (d -> next != NULL)
00359 d = d -> next;
00360 else {
00361 d -> next = (ac_decoder *) malloc(sizeof(ac_decoder));
00362 d = d -> next;
00363 d -> check = (ac_dec_list *) malloc(sizeof(ac_dec_list));
00364 d -> check -> name = NewString(l -> name);
00365 d -> check -> value = l -> value;
00366 d -> found = NULL;
00367 d -> subcheck = NULL;
00368 d -> next = NULL;
00369 }
00370 }
00371 }
00372
00373 d -> found = instruction;
00374 d -> subcheck = NULL;
00375
00376 return base;
00377 }
00378
00379
00380 ac_decoder_full *CreateDecoder(ac_dec_format *formats, ac_dec_instr *instructions)
00381 {
00382 ac_dec_field *field, *allFields;
00383 ac_dec_format *format = formats;
00384
00385 ac_dec_instr *instr = instructions;
00386 ac_decoder *dec;
00387 ac_decoder_full *full;
00388 unsigned nFields = 0, nFormats = 0;
00389
00390 while (format) {
00391 int format_size = 0;
00392 nFormats ++;
00393 field = format -> fields;
00394 while (field) {
00395 format_size += field->size;
00396 nFields++;
00397 field = field -> next;
00398 }
00399 format->size = format_size;
00400 format = format -> next;
00401 }
00402 nFields++;
00403 allFields = PutIDs(formats, nFields);
00404
00405 dec = NULL;
00406
00407 while (instr) {
00408 dec = AddToDecoder(dec, instr, allFields);
00409 instr->size = FindFormat(formats, instr->format)->size / 8;
00410 instr = instr -> next;
00411 }
00412
00413 full = malloc(sizeof(ac_decoder_full));
00414
00415 full -> decoder = dec;
00416 full -> formats = formats;
00417 full -> fields = allFields;
00418 full -> instructions = instructions;
00419 full -> nFields = nFields;
00420
00421 return full;
00422 }
00423
00424
00425 ac_dec_instr *FindInstruction(ac_decoder_full *decoder, unsigned char *buffer, int quant)
00426 {
00427 ac_decoder *d = decoder -> decoder;
00428
00429 ac_dec_field *field = 0;
00430 long long field_value;
00431
00432
00433 ac_decoder *chosenPath[64];
00434 int chosenPathPos = 0;
00435 chosenPath[chosenPathPos] = d;
00436
00437 while (d) {
00438 if (!field) {
00439 field = FindDecField(decoder -> fields, d -> check -> name);
00440 field_value = GetBits(buffer, &quant, field -> first_bit, field -> size, field -> sign);
00441 }
00442
00443
00444
00445
00446 if (field_value == d -> check -> value) {
00447 if (d -> found) {
00448
00449 return d -> found;
00450 } else {
00451
00452 chosenPath[++chosenPathPos] = d -> subcheck;
00453 d = d -> subcheck;
00454 field = 0;
00455 }
00456 } else {
00457
00458 chosenPath[chosenPathPos] = d -> next;
00459 d = d -> next;
00460 if (d && strcmp(d->check->name, field->name) != 0)
00461 field=0;
00462 }
00463
00464 while ((d == NULL) && (chosenPathPos > 0)) {
00465
00466 d = chosenPath[--chosenPathPos];
00467 d = d -> next;
00468 if (d && strcmp(d -> check -> name, field -> name) != 0)
00469 field = 0;
00470 }
00471 }
00472
00473 return NULL;
00474 }
00475
00476
00477 ac_dec_format *FindFormat(ac_dec_format *formats, char *name)
00478 {
00479 ac_dec_format *format = formats;
00480
00481 while(format && (strcmp(format -> name, name) != 0)) {
00482 format = format -> next;
00483 }
00484 if (!format) {
00485 fprintf(stderr, "Invalid format name %s.\n", name);
00486 exit(1);
00487 }
00488 return format;
00489 }
00490
00491
00492 ac_dec_instr *GetInstrByID(ac_dec_instr *instr, int id)
00493 {
00494 for (; instr && instr->id != id;) {
00495 instr = instr->next;
00496 }
00497 if (!instr) {
00498 fprintf(stderr, "Invalid instruction ID %d.\n", id);
00499 exit(1);
00500 }
00501 return instr;
00502 }
00503
00504
00505 unsigned *DecodeAsInstruction(ac_decoder_full * decoder, ac_dec_instr *instruction, unsigned char *buffer, int quant)
00506 {
00507 static unsigned *fields = 0;
00508 unsigned counter;
00509 ac_dec_field *field;
00510
00511 ac_dec_field *list ;
00512
00513 ac_dec_format *format;
00514
00516 if (!fields) fields = (unsigned *) malloc(sizeof(unsigned) * decoder -> nFields);
00517
00519 format = FindFormat(decoder->formats, instruction->format);
00520
00522 list = format -> fields;
00523
00524 for (counter = 1; counter < decoder -> nFields; counter ++)
00525 fields[counter] = 0;
00526
00527 while (list) {
00528 field = FindDecField(decoder -> fields, list -> name);
00529 if (!field) {
00530 fprintf(stderr, "Invalid field name %s.\n", list -> name);
00531 exit(1);
00532 }
00533 fields[field -> id] = GetBits(buffer, &quant, field -> first_bit, field -> size, field -> sign);
00534 list = list -> next;
00535 }
00536
00537 fields[0] = instruction -> id;
00538 return fields;
00539 }
00540
00541
00542 unsigned *Decode(ac_decoder_full *decoder, unsigned char *buffer, int quant)
00543 {
00544 ac_dec_instr *instruction;
00545
00546 instruction = FindInstruction(decoder, buffer, quant);
00547
00548 if (instruction != NULL) {
00549 return DecodeAsInstruction(decoder, instruction, buffer, quant);
00550 }
00551
00552 return NULL;
00553 }