Annotation of researchv9/cmd/sun/as/instruction.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)instruction.c 1.1 86/02/03 Copyr 1985 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "as.h"
                     10: #if C2
                     11: #include "c2.h"
                     12: #endif
                     13: 
                     14: extern char *malloc();
                     15: struct oper *newoperand();
                     16: struct oper  operands[OPERANDS_MAX];
                     17: int numops, code_length;
                     18: 
                     19: #if C2
                     20: NODE first = { OP_FIRST, SUBOP_OTHER, &first, &first };
                     21: 
                     22: /* does this branch read the c or v bit of the condition code? */
                     23: char read_cc_cv[]={ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0 };
                     24: static struct ins_bkt * moveq = NULL;
                     25: #endif
                     26: 
                     27: instruction( ip )
                     28:     register struct ins_bkt *ip;
                     29: {
                     30: #if C2
                     31:     register NODE *np;
                     32: #endif
                     33:     register i;
                     34: 
                     35:     if ((ip->xflags_i&I20) && !ext_instruction_set)
                     36:        PROG_ERROR( E_OPCODE );
                     37:     i = 0;
                     38:     if (ip->noper_i != numops && ip->noper_i <= OPERANDS_MAX){
                     39:        if ( (ip->touchop_i&TOUCH1(TOUCHMASK)) == TOUCH1(SPEC(2)) && numops==1 && ip->subop_i == SUBOP_W )
                     40:            /* shifts are a special case...*/
                     41:            i = 0;
                     42:        else if ( (ip->touchop_i&TOUCH1(TOUCHMASK)) == TOUCH1(SPEC(6)) && numops==0 )
                     43:            /* so is rts */
                     44:            i = 0;
                     45:        else
                     46:            i = (E_NUMOPS);
                     47:     } else switch (ip->noper_i){
                     48:     default: i = 0; break;
                     49:     case 1:
                     50:            i = operand_ok( ip, &operands[0], (struct oper *)NULL, (struct oper *)NULL); break;
                     51:     case 2:
                     52:            i = operand_ok( ip, &operands[0], &operands[1], (struct oper *)NULL);break;
                     53:     case 3:
                     54:            i = operand_ok( ip, &operands[0], &operands[1], &operands[2] );break;
                     55:     }
                     56:     if (i)
                     57:        PROG_ERROR(i);
                     58:     if (ip->align_i & dot) /* don't want instructions on odd bounds */
                     59:            PROG_ERROR(E_ODDADDR);
                     60: #if AS
                     61:     if (ISINSTRUC( ip->op_i ) )
                     62:            code_length = 2; /* all instructions at least this long */
                     63: #endif
                     64:     (ip->routine_i)(ip, numops);
                     65: #if AS
                     66:     if (code_length) {
                     67:          put_words(code,code_length);  /* output text */
                     68:          bc = code_length;             /* increment LC */
                     69:     }
                     70: #endif
                     71: }
                     72: 
                     73: 
                     74: static unsigned
                     75: op_to_bits( op )
                     76:     register struct oper *op;
                     77: {
                     78:     /* return the address-mode bits for operand *op */
                     79:     register unsigned s; 
                     80:     static unsigned bits[] = {
                     81:        0,
                     82:        AM_REG, AM_DEFER, AM_POSTINC, AM_PREDEC, AM_DISPL,
                     83:        AM_INDEX, AM_ABSS, AM_ABSL, AM_IMMED, AM_NORMAL, 
                     84:        AM_REGPAIR, -1, -1, -1, -1,
                     85:        AM_REGLIST,AM_FREGLIST,AM_FCREGLIST
                     86:     };
                     87:     switch ( s = bits[(int)op->type_o]){
                     88:     case AM_REG:
                     89:        s = reg_access[op->value_o]; break;
                     90:     case AM_DISPL:
                     91:        if (op->reg_o == PCREG) s = AM_PCDISPL; break;
                     92:     case AM_INDEX:
                     93:        if (op->reg_o == PCREG) s = AM_PCINDEX; break;
                     94:     }
                     95:     return s;
                     96: }
                     97: 
                     98: int
                     99: operand_ok( ip, op1, op2, op3 )
                    100:     struct ins_bkt *ip;
                    101:     struct oper    *op1, *op2, *op3;
                    102: {
                    103:     /*
                    104:      * this routine answers the eternal question:
                    105:      *  are operands *op1 and *op2 ok to use as the operands of instruction *ip?
                    106:      * it does it by looking at the optype_i bit fields in the instruction
                    107:      * description.
                    108:      */
                    109:     register i;
                    110:     register unsigned opbits1, opbits2, opbits3;
                    111:     register noperands = ip->noper_i;
                    112: 
                    113:     op1->access_o = opbits1 = op_to_bits( op1 );
                    114:     if (op2)
                    115:        op2->access_o = opbits2 = op_to_bits( op2 );
                    116:     else
                    117:        opbits2 = 0;
                    118:     if (op3)
                    119:        op3->access_o = opbits3 = op_to_bits( op3 );
                    120:     else
                    121:        opbits3 = 0;
                    122:     switch (ip->touchop_i&TOUCH2(TOUCHMASK)){
                    123:     case TOUCH2(SPEC(2)):
                    124:        /* special hackery for shifts */
                    125:        if (opbits1 == AM_IMMED && ((i=op1->value_o)<1 || i>8 || op1->sym_o))
                    126:            return E_CONSTANT;
                    127:        break;
                    128:     } 
                    129:     switch (ip->touchop_i&TOUCH1(TOUCHMASK)){
                    130:     case TOUCH1(SPEC(0)):
                    131:     case TOUCH1(SPEC(1)):
                    132:        /* special hackery for bit ops */
                    133:        if (opbits1 == AM_IMMED){
                    134:            i = op1->value_o;
                    135:            if (op1->sym_o) return E_CONSTANT;
                    136:            if (opbits2 == AM_DREG){
                    137:                if (i < 0 || i > 31 ) return E_CONSTANT;
                    138:            } else 
                    139:                if (i < 0 || i > 7 ) return E_CONSTANT;
                    140:        }
                    141:        break;
                    142:     }
                    143:     switch (noperands){
                    144:     case 0: return 0;
                    145:     case 1:
                    146:        for (i=0; i<N_OPTYPES; i+=1)
                    147:            if (opbits1&ip->optype_i[i]) return 0;
                    148:        break;
                    149:     case 2:
                    150:        for (i=0; i<N_OPTYPES; i+=2)
                    151:            if ((opbits1&ip->optype_i[i]) && (opbits2&ip->optype_i[i+1]) ) return 0;
                    152:        break;
                    153:     case 3:
                    154:        for (i=0; i<N_OPTYPES; i+=3)
                    155:            if ((opbits1&ip->optype_i[i]) && (opbits2&ip->optype_i[i+1]) && (opbits3&ip->optype_i[i+2]) ) return 0;
                    156:        break;
                    157:     }
                    158:     return E_OPERAND;
                    159: }
                    160: 
                    161: 
                    162: /* table used to determine node type. */
                    163: /* 
                    164:  * we would really like this table to be subscripted by the enumerated type
                    165:  * opcode_t, but C cannot hack that. Order here is VERY IMPORTANT,
                    166:  * and this table must change if the opcode order or number changes!!
                    167:  */
                    168: char opcodetypes[] = {
                    169:        0, 0, 0,                        /* FIRST, COMMENT, LABEL */
                    170:        PSEUDOCODE, PSEUDOCODE,         /* LONG, WORD */
                    171:        PSEUDOCODE, PSEUDONOCODE,       /* BYTE,TEXT */
                    172:        PSEUDONOCODE, PSEUDONOCODE,     /* DATA, DATA1 */
                    173:        PSEUDONOCODE, PSEUDONOCODE,     /* DATA2, BSS */
                    174:        PSEUDONOCODE,                   /* PROC */
                    175:        PSEUDONOCODE, PSEUDONOCODE,     /* GLOBL, COMM */
                    176:        PSEUDOCODE, PSEUDOCODE,         /* EVEN, ALIGN */
                    177:        PSEUDOCODE, PSEUDOCODE,         /* ASCIZ, ASCII */
                    178:        PSEUDOCODE, PSEUDOCODE,         /* FLOAT, DOUBLE */
                    179:        PSEUDONOCODE,                   /* STABS */
                    180:        PSEUDONOCODE, PSEUDONOCODE,     /* STABD, STABN */
                    181:        PSEUDOCODE, PSEUDONOCODE,       /* SKIP, LCOMM */
                    182:        PSEUDONOCODE,                   /* CPID */
                    183:        INSTRTYPE, INSTRTYPE,           /* CSWITCH, FSWITCH */
                    184:        INSTRTYPE, INSTRTYPE,           /* BRANCH, MOVE */
                    185:        INSTRTYPE, INSTRTYPE,           /* MOVEM, EXIT */
                    186:        INSTRTYPE, INSTRTYPE,           /* DBRA, CALL */
                    187:        INSTRTYPE, INSTRTYPE,           /* JUMP, DJMP */
                    188:        INSTRTYPE, INSTRTYPE,           /* LINK, CMP */
                    189:        INSTRTYPE, INSTRTYPE,           /* PEA, ADD */
                    190:        INSTRTYPE, INSTRTYPE,           /* AND, EXT */
                    191:        INSTRTYPE, INSTRTYPE,           /* OR, TST */
                    192:        INSTRTYPE, INSTRTYPE,           /* ASL, ASR */
                    193:        INSTRTYPE, INSTRTYPE,           /* SUB, UNLK */
                    194:        INSTRTYPE, INSTRTYPE,           /* LEA, CLR */
                    195:        INSTRTYPE, INSTRTYPE,           /* BOP, EOR */
                    196:        INSTRTYPE,                      /* OTHER */
                    197: };

unix.superglobalmegacorp.com

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