Annotation of 43BSDReno/sys/tahoealign/Aoperand.c, revision 1.1.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.