- char *op, op1[256], op2[256];
- int opsize;
- const char *p;
-
- while (*inst && isspace(*inst)) inst++;
-
- #define ISINST(s) (strncmp(inst, (s), sizeof(s)-1) == 0)
-
- /* Based on the current (2003-08-22) code generation for the
- small library, the top instruction probability is:
-
- 57% mov/movx/movc
- 6% push
- 6% pop
- 4% inc
- 4% lcall
- 4% add
- 3% clr
- 2% subb
- */
- /* mov, push, & pop are the 69% of the cases. Check them first! */
- if (ISINST("mov"))
- {
- if (*(inst+3)=='x') return 1; /* movx */
- if (*(inst+3)=='c') return 1; /* movc */
- goto checkoperands; /* mov */
- }
- if (ISINST("push")) return 2;
- if (ISINST("pop")) return 2;
-
- if (ISINST("lcall")) return 3;
- if (ISINST("ret")) return 1;
- if (ISINST("ljmp")) return 3;
- if (ISINST("sjmp")) return 2;
- if (ISINST("rlc")) return 1;
- if (ISINST("rrc")) return 1;
- if (ISINST("rl")) return 1;
- if (ISINST("rr")) return 1;
- if (ISINST("swap")) return 1;
- if (ISINST("jc")) return 2;
- if (ISINST("jnc")) return 2;
- if (ISINST("jb")) return 3;
- if (ISINST("jnb")) return 3;
- if (ISINST("jbc")) return 3;
- if (ISINST("jmp")) return 1; // always jmp @a+dptr
- if (ISINST("jz")) return 2;
- if (ISINST("jnz")) return 2;
- if (ISINST("cjne")) return 3;
- if (ISINST("mul")) return 1;
- if (ISINST("div")) return 1;
- if (ISINST("da")) return 1;
- if (ISINST("xchd")) return 1;
- if (ISINST("reti")) return 1;
- if (ISINST("nop")) return 1;
- if (ISINST("acall")) return 1;
- if (ISINST("ajmp")) return 2;
-
-checkoperands:
- p = inst;
- while (*p && isalnum(*p)) p++;
- for (op = op1, opsize=0; *p && *p != ',' && opsize < sizeof(op1); p++) {
- if (!isspace(*p)) *op++ = *p, opsize++;
- }
- *op = '\0';
- if (*p == ',') p++;
- for (op = op2, opsize=0; *p && *p != ',' && opsize < sizeof(op2); p++) {
- if (!isspace(*p)) *op++ = *p, opsize++;
- }
- *op = '\0';
-
- #define IS_A(s) (*(s) == 'a' && *(s+1) == '\0')
- #define IS_C(s) (*(s) == 'c' && *(s+1) == '\0')
- #define IS_Rn(s) (*(s) == 'r' && *(s+1) >= '0' && *(s+1) <= '7')
- #define IS_atRi(s) (*(s) == '@' && *(s+1) == 'r')
-
- if (ISINST("mov")) {
- if (IS_C(op1) || IS_C(op2)) return 2;
- if (IS_A(op1)) {
- if (IS_Rn(op2) || IS_atRi(op2)) return 1;
- return 2;
- }
- if (IS_Rn(op1) || IS_atRi(op1)) {
- if (IS_A(op2)) return 1;
- return 2;
- }
- if (strcmp(op1, "dptr") == 0) return 3;
- if (IS_A(op2) || IS_Rn(op2) || IS_atRi(op2)) return 2;
- return 3;
- }
- if (ISINST("add") || ISINST("addc") || ISINST("subb") || ISINST("xch")) {
- if (IS_Rn(op2) || IS_atRi(op2)) return 1;
- return 2;
- }
- if (ISINST("inc") || ISINST("dec")) {
- if (IS_A(op1) || IS_Rn(op1) || IS_atRi(op1)) return 1;
- if (strcmp(op1, "dptr") == 0) return 1;
- return 2;
- }
- if (ISINST("anl") || ISINST("orl") || ISINST("xrl")) {
- if (IS_C(op1)) return 2;
- if (IS_A(op1)) {
- if (IS_Rn(op2) || IS_atRi(op2)) return 1;
- return 2;
- } else {
- if (IS_A(op2)) return 2;
- return 3;
- }
- }
- if (ISINST("clr") || ISINST("setb") || ISINST("cpl")) {
- if (IS_A(op1) || IS_C(op1)) return 1;
- return 2;
- }
- if (ISINST("djnz")) {
- if (IS_Rn(op1)) return 2;
- return 3;
- }
-
- if (*inst == 'a' && *(inst+1) == 'r' && *(inst+2) >= '0' && *(inst+2) <= '7' && op1[0] == '=') {
- /* ignore ar0 = 0x00 type definitions */
- return 0;
- }
-
- fprintf(stderr, "Warning, peephole unrecognized instruction: %s\n", inst);
- return 3;