|
|
1.1 ! root 1: #include "../machine/alignment.h" ! 2: #define illegal(x) ((look_at->add_modes & x)==0) ! 3: #define legal(x) !illegal(x) ! 4: ! 5: struct oprnd *operand(infop, number) ! 6: register process_info *infop; ! 7: int number; ! 8: /* ! 9: * Enter with pc pointing to an operand descriptor ! 10: * in the 'text'. Decode the addressing mode, get ! 11: * the effective address and some data from there. ! 12: * Leave pc on the next oerand specifier or opcode. ! 13: * Returns a pointer to a 'decoded operand' structure, ! 14: * actually one of the 4 pre-allocated . ! 15: * ! 16: * This routine should be called in such a sequence ! 17: * that pc will not have to be backed up to get some ! 18: * operand. For example, operand(0) and then operand(1) ! 19: * and then operand(2) is OK. Even operand(0), operand(1), ! 20: * operand(1) is OK. The rule is that operand(N) should not ! 21: * be called before operand(N-1) was. ! 22: * ! 23: ***********************************************************/ ! 24: { ! 25: register struct oprnd *next; ! 26: register struct operand_des *look_at; ! 27: register int header,reg_num,shift_count, displ; ! 28: register int keep_last; ! 29: ! 30: next = &decoded[number]; ! 31: if (number <= last_operand) return(next); ! 32: if (number == last_operand+1) last_operand = number; ! 33: else ! 34: { ! 35: printf ("Wrong sequence of OPERAND calls (alignment code)\n"); ! 36: return (&decoded[number]); ! 37: }; ! 38: look_at = &Table[opCODE].operand[number]; ! 39: next->data2 = 0; /* Prepare for quad fetch */ ! 40: next->length = look_at->length; ! 41: if (look_at->add_modes == Brd) ! 42: { ! 43: next->mode = Add; ! 44: switch(look_at->length) ! 45: { ! 46: case 1: ! 47: displ = get_byte(infop, pc); ! 48: pc++; ! 49: break; ! 50: case 2: ! 51: displ = get_word(infop, pc); ! 52: pc +=2; ! 53: break; ! 54: default: ! 55: printf ("Wrong branch displacement(alignment code)\n"); ! 56: }; ! 57: next->address = pc+displ; ! 58: return(next); ! 59: }; ! 60: ! 61: /* Not branch displacement, real operand */ ! 62: header = get_byte(infop, pc) & 0xff; ! 63: pc++; ! 64: reg_num = header & 0xf; ! 65: switch (header >> 4 & 0xf) { ! 66: case 0: /* Short literals */ ! 67: case 1: ! 68: case 2: ! 69: case 3: ! 70: if (illegal(Lit)) exception(infop, ILL_ADDRMOD); ! 71: next->mode = Imm; ! 72: next->data = header; ! 73: break; ! 74: ! 75: case 4: /* Indexed register */ ! 76: if (illegal(Add) || reg_num==PCOUNTER || reg_num==SPOINTER) ! 77: exception (infop, ILL_ADDRMOD); ! 78: keep_last = last_operand; ! 79: last_operand = number - 1; /* To get real results */ ! 80: next = operand(infop, number); /* Get base address (recursive) */ ! 81: last_operand = keep_last; ! 82: if ! 83: (! (next->mode & Indx)) exception (infop, ILL_ADDRMOD); ! 84: switch (look_at->length) ! 85: { ! 86: case 1: ! 87: shift_count = 0; ! 88: break; ! 89: case 2: ! 90: shift_count = 1; ! 91: break; ! 92: case 4: ! 93: shift_count = 2; ! 94: break; ! 95: case 8: ! 96: shift_count = 3; ! 97: break; ! 98: default: ! 99: printf("Wrong data length in table(alignment code)\n"); ! 100: }; ! 101: next->address += (Register(infop,reg_num) << shift_count); ! 102: next->mode |= (look_at->add_modes & M); /* Set R/W bits */ ! 103: trytoread (infop,next,number); ! 104: break; ! 105: ! 106: case 5: /* Direct register */ ! 107: if (illegal (Dir) || reg_num==PCOUNTER || ! 108: reg_num==SPOINTER && legal(R)) exception (infop, ILL_ADDRMOD); ! 109: next->mode = Dir; ! 110: next->data = Register(infop,reg_num); ! 111: next->mode |= (look_at->add_modes & M); /* Set R/W bits */ ! 112: next->reg_number = reg_num; ! 113: if (look_at->length == 8) ! 114: { ! 115: if (reg_num >= SPOINTER-1 || (reg_num & 1)==1 ) ! 116: exception (infop, ILL_ADDRMOD); ! 117: else next->data2 = Register(infop,reg_num+1); ! 118: }; ! 119: break; ! 120: ! 121: case 6: /* Indirect register */ ! 122: if (illegal(Add) || reg_num==PCOUNTER ) ! 123: exception (infop, ILL_ADDRMOD); ! 124: next->mode = Add; ! 125: next->mode |= (look_at->add_modes & M); /* Set R/W bits */ ! 126: if (reg_num != SPOINTER) next->mode |= Indx; /* (sp) not indexable*/ ! 127: next->reg_number = reg_num; ! 128: next->address = Register(infop,reg_num); ! 129: trytoread (infop,next,number); ! 130: break; ! 131: ! 132: case 7: /* Autodecrement SP */ ! 133: if (illegal(Add) || reg_num!=SPOINTER || look_at->length != 4 || ! 134: legal(R)) exception (infop, ILL_ADDRMOD); ! 135: next->mode = SPmode; /* Implies Add */ ! 136: next->mode |= W; /* Set R/W bits */ ! 137: next->reg_number = SPOINTER; ! 138: next->length = 4; /* Regardless of big table */ ! 139: sp -= 4; ! 140: next->address = sp; ! 141: break; ! 142: ! 143: case 8: /* Immediate or (sp)+ */ ! 144: switch (reg_num) { ! 145: case 8: /* Immediate byte */ ! 146: if (illegal(Imm)) exception (infop, ILL_ADDRMOD); ! 147: next->mode = Imm; ! 148: next->data = get_byte(infop, pc); ! 149: pc++; ! 150: break; ! 151: case 9: /* Immediate word */ ! 152: if (illegal(Imm)) exception (infop, ILL_ADDRMOD); ! 153: next->mode = Imm; ! 154: next->data = get_word(infop, pc); ! 155: pc +=2; ! 156: break; ! 157: case 0xf : /* Immediate longword */ ! 158: if (illegal(Imm)) exception (infop, ILL_ADDRMOD); ! 159: next->mode = Imm; ! 160: next->data = get_longword(infop, pc); ! 161: pc +=4; ! 162: break; ! 163: case 0xe: /* Autoincrement sp */ ! 164: if (illegal(Add) || legal(W) || ! 165: look_at->length != 4) exception (infop, ILL_ADDRMOD); ! 166: next->mode = SPmode; /* Implies Add */ ! 167: next->reg_number = SPOINTER; ! 168: next->address = sp; ! 169: next->data = get_longword(infop, sp); ! 170: next->length = 4; /* Regardless of big table */ ! 171: sp += 4; ! 172: break; ! 173: default: ! 174: exception (infop, ILL_ADDRMOD); ! 175: }; ! 176: if (look_at -> length == 8) /* Quadword fetch,not (sp)+ */ ! 177: { ! 178: next->data2 = next->data; ! 179: if (next->data2 >= 0) next->data = 0; ! 180: else next->data = -1; ! 181: } ! 182: break; ! 183: ! 184: case 9: /* Autoincrement deferred SP or PC */ ! 185: if (reg_num !=PCOUNTER && reg_num !=SPOINTER ) ! 186: exception (infop, ILL_ADDRMOD); ! 187: if (reg_num == PCOUNTER && illegal(Abs) || ! 188: reg_num == SPOINTER && illegal(Add)) ! 189: exception (infop, ILL_ADDRMOD); ! 190: next->mode = Add | (look_at->add_modes & M) | Indx; ! 191: next->address = get_longword (infop, (reg_num == PCOUNTER)?pc : sp ); ! 192: Replace (infop,reg_num, Register(infop,reg_num)+4); ! 193: trytoread (infop,next,number); ! 194: break; ! 195: ! 196: case 0xa: /* Register or PC + byte displacement */ ! 197: if (reg_num != PCOUNTER && illegal(Add) || ! 198: reg_num == PCOUNTER && illegal(Pcrel) ) exception (infop, ILL_ADDRMOD); ! 199: next->mode = Add | (look_at->add_modes & M); ! 200: if (reg_num != SPOINTER && ! 201: look_at->add_modes != PR) next->mode |= Indx; ! 202: displ = get_byte(infop,pc); ! 203: pc++; ! 204: next->address = Register(infop,reg_num)+displ; ! 205: trytoread (infop,next,number); ! 206: break; ! 207: ! 208: case 0xb: /* Same, indirect */ ! 209: if (illegal(Add)) exception (infop, ILL_ADDRMOD); ! 210: next->mode = Add | (look_at->add_modes & M) | Indx; ! 211: displ = get_byte(infop,pc); ! 212: pc++; ! 213: next->address = get_longword(infop, Register(infop,reg_num)+displ); ! 214: trytoread (infop,next,number); ! 215: break; ! 216: ! 217: case 0xc: /* Register or PC + word displacement */ ! 218: if (reg_num != PCOUNTER && illegal(Add) || ! 219: reg_num == PCOUNTER && illegal(Pcrel) ) exception (infop, ILL_ADDRMOD); ! 220: next->mode = Add | (look_at->add_modes & M); ! 221: if (reg_num != SPOINTER && ! 222: look_at->add_modes != PR) next->mode |= Indx; ! 223: displ = get_word(infop,pc); ! 224: pc +=2; ! 225: next->address = Register(infop,reg_num)+displ; ! 226: trytoread (infop,next,number); ! 227: break; ! 228: ! 229: case 0xd: /* Same, indirect */ ! 230: if (illegal(Add)) exception (infop, ILL_ADDRMOD); ! 231: next->mode =Add | (look_at->add_modes & M) | Indx ; ! 232: displ = get_word(infop,pc); ! 233: pc +=2; ! 234: next->address = get_longword (infop,Register(infop,reg_num)+displ); ! 235: trytoread (infop,next,number); ! 236: break; ! 237: ! 238: ! 239: case 0xe: /* Register or PC + longword displacement */ ! 240: if (reg_num != PCOUNTER && illegal(Add) || ! 241: reg_num == PCOUNTER && illegal(Pcrel) ) exception (infop, ILL_ADDRMOD); ! 242: next->mode = Add | (look_at->add_modes & M); ! 243: if (reg_num != SPOINTER && ! 244: look_at->add_modes != PR) next->mode |= Indx; ! 245: displ = get_longword(infop,pc); ! 246: pc += 4; ! 247: next->address = Register(infop,reg_num)+displ; ! 248: trytoread (infop,next,number); ! 249: break; ! 250: ! 251: case 0xf: /* Same, indirect */ ! 252: if (illegal(Add)) exception (infop, ILL_ADDRMOD); ! 253: next->mode = Add | (look_at->add_modes & M) | Indx; ! 254: displ = get_longword(infop,pc); ! 255: pc +=4; ! 256: next->address = get_longword(infop, Register(infop,reg_num)+displ); ! 257: trytoread (infop,next,number); ! 258: }; ! 259: return(next); ! 260: } ! 261: ! 262: ! 263: trytoread (infop,pointer,number) ! 264: process_info *infop; ! 265: struct oprnd *pointer; ! 266: int number; ! 267: /* ! 268: /* Receives the opcode operand number and a pointer ! 269: /* to the 'decoded' operand structure. ! 270: /* If it's defined as readable data in the big table, ! 271: /* it returns the data, sign extended. ! 272: /* ! 273: /**********************************************************/ ! 274: ! 275: { ! 276: register struct operand_des *look_at; ! 277: ! 278: ! 279: look_at = &Table[opCODE].operand[number]; ! 280: if (legal(R)) ! 281: switch (look_at->length) ! 282: { ! 283: case 1: ! 284: pointer->data = get_byte (infop,pointer->address); ! 285: break; ! 286: case 2: ! 287: pointer->data = get_word (infop,pointer->address); ! 288: break; ! 289: case 4: ! 290: pointer->data = get_longword (infop,pointer->address); ! 291: break; ! 292: case 8: ! 293: pointer->data = get_longword (infop,pointer->address); ! 294: pointer->data2 = get_longword (infop,pointer->address+4); ! 295: break; ! 296: default: ! 297: printf ("Wrong data length in table (alignment code)\n"); ! 298: }; ! 299: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.