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