Annotation of 43BSDTahoe/sys/tahoealign/Aoperand.c, revision 1.1

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

unix.superglobalmegacorp.com

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