Annotation of cci/sys/tahoe/Aoperand.c, revision 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.