Annotation of cci/sys/tahoe/Aoperand.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.